pro*_*avi 2 java generics covariance java-8 method-reference
下面的第一个作业无法编译,但我不确定为什么,静态方法的方法签名与函数方法签名匹配,尽管它不使用类型参数。尽管第二行除了类型参数化之外具有相同的签名,但编译良好。
这背后的原因是什么?
public class GenericSample<T> {
public static void staticLambdaMtd(Integer a) {
}
public static<X> void staticLambdaMtd2(X a) {
}
// Funca<T> fa1 = GenericSample::staticLambdaMtd;//does not compile !
Funca<T> fa = GenericSample::staticLambdaMtd2;//does compile !
}
interface Funca<A> {
public void funct(A a);
}
Run Code Online (Sandbox Code Playgroud)
您正在混合通用参数T和类型Integer。这是行不通的,因为T和Integer是不同的类型。
泛型是不变的。这意味着您只能分配给List<Person>具有相同通用参数的另一个列表,即Person(notInteger或Cat)T。同样,我们不能分配Funca<Integer>给类型的变量Funca<T>。
有关详细信息,请查看Oracle 提供的本教程。
使用静态方法创建的函数staticLambdaMtd(Integer a)只能分配给类型为 的变量Funca<Integer>,但不能Funca<T>分配给任意类型的函数,因为只有Integer类型会与方法签名匹配,但不能与class 时定义的任何类型(如String、Cat、 )相匹配BigDecimalGenericSample )相匹配将被实例化。
第二条语句编译得很好,因为它不需要任何特定类型。X只是一个占位符,以及T. 表达式GenericSample::staticLambdaMtd2应该被归类为所谓的多表达式,即因为您没有提供类型编译器需要从赋值上下文中推断它。
因此,表达式GenericSample::staticLambdaMtd2将被推断为类型Funca<T>,第二条语句将编译良好。
下面显示的所有分配均有效:
// expression on the right could represent only `Funca<Integer>`
Funca<Integer> fa1 = GenericSample::staticLambdaMtd;
// expression on the right can be succefully inferred to
// a function of any type based on the assingment context on the left
Funca<T> fa = GenericSample::staticLambdaMtd2;
Funca<String> fa = GenericSample::staticLambdaMtd2;
Funca<BigDecimal> fa = GenericSample::staticLambdaMtd2;
Run Code Online (Sandbox Code Playgroud)
请注意,通过提供通用参数,可以将表达式从聚合GenericSample::staticLambdaMtd2表达式转换为“独立形式” (事实上,规范中提供的定义方法引用始终是聚合表达式,因此我在引号中使用了“独立”含义)仅该赋值上下文将被忽略)。
我们如何打破它:
// that will not compile for the same reason as the the firt statement doesn't compile
Funca<T> fa3 = GenericSample::<Integer>staticLambdaMtd2;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
154 次 |
| 最近记录: |