java - 方法引用,协方差逆变

标签 java java-8

我刚刚发现 java 8 允许引用具有更具体的返回类型和更通用的参数的方法。

import java.util.function.Function;

public class MethodReferences {
    public static Integer function(Object o) {
        return 2;
    }

    public static void main(String[] args) {
        Function<String, Object> function = MethodReferences::function;
    }
}

这非常灵活。

但是为什么他们没有将其扩展到其他情况呢?

例如:

import java.util.function.Function;

public class Main {


    public static void main(String[] args) {
        Function<String, Object> function = function();
    }

    private static Function<Object, Integer> function() {
        return new Function<Object, Integer>() {

            @Override
            public Integer apply(Object o) {
                return 1;
            }
        };
    }
}

编译失败:

Type mismatch: cannot convert from Function<Object,Integer> to Function<String,Object>

最佳答案

这是泛型的一个简单限制。类型系统不知道 Object 中的哪一个和Integer是返回类型和参数类型,因此它不能执行任何协变/逆变智能。

如果你想表达“一个接受父类(super class)型 X 并返回子类型 Y 的函数”,你可以这样做 Function<? super X, ? extends Y> 。事实上,如果你改变

Function<String, Object> function = function();

Function<? super String, ? extends Object> function = function();

你的代码可以编译。 ( ? extends Object? 相同,但为了清楚起见,我将其写出来)

关于java - 方法引用,协方差逆变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24636482/

相关文章:

java - 将 Set<E> 转换为 String[] 会给出错误顺序的元素

java - 对对象数组进行二分查找以查找元素的字段

java - IBM java8 BigDecimal 与 MathContext.DECIMAL64 的 float 问题

java-8 - Java 8 将整数流映射到 <T> 流

python - 使用 FFMPEG 从 Android 流式传输图像

java - 禁用 dbcp 连接池的重试

java - JDK8 中的动态数组

java-8 - 用双列表示法结合函数和消费者

java - 如何为 CompletableFutures 提供 ThreadLocal?

java - 如何从 Instant 和时间字符串构造 ZonedDateTime?