我刚刚发现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>
答案 0 :(得分:9)
这是泛型的简单限制。类型系统不知道Object
和Integer
中的哪一个是返回类型和参数类型,因此它不能做任何协方差/逆变智能。
如果你想表达&#34;一个超类型为X
且返回Y
&#34; 的子类型的函数,你会{{1 }}。事实上,如果你改变了
Function<? super X, ? extends Y>
到
Function<String, Object> function = function();
你的代码编译。 (Function<? super String, ? extends Object> function = function();
与? extends Object
相同,但为了清楚起见,我将其写出来)
答案 1 :(得分:0)
函数在参数类型上应始终是协变的,而在返回类型上则应协变。
A2 instanceof A1
和B1 instanceof B2
然后
(A1 -> B1) instanceof (A2 -> B2) // A1 -> B1 means function that takes argument of type A1 and returns value of type B1
对于函数是一等公民的任何编程语言,这都应该是正确的。函数不是Java中的一流实体,因此语言设计人员不可能强加这种差异。 (显然,上面的intanceof在Java中没有意义,因为它的功能不是任何实例。它们只是Java设计师的最后努力,以确保Java在大数据和Apache Spark时代保持相关性。所有“功能”功能是从scala借来的。