我知道这可能与泛型和协变返回类型有关。但我撑不过去了。
给出了Apple扩展果树的两个类。
public class TestReturnValue {
public static Supplier<? extends Fruit> conFruitExt = Apple::new;
public static Supplier<Fruit> conFruit = Apple::new; // Compiles
public static final Supplier<Fruit> supApple = supplyApple(); // Compile ERROR
private static Supplier<Apple> supplyApple() {
return Apple::new;
}
public static void main(String[] args) {
Fruit fruitExt = conFruitExt.get();
Fruit fruit = conFruit.get();
System.out.println(fruitExt);
System.out.println(fruit);
}
}conFruitExt和conFruit有什么不同?它们都是 apple 的构造器,并调用get()创建苹果实例。
附加的? extends部分的conFruitExt类型有什么不同吗?
Update1 2020/11/19
正如建议的答案说的那样,jonrsharpe的question mark in generic,Supplier<Fruit>不编译到Suppier<Apple>,所以public static final Supplier<Fruit> supApple = TestReturnValue::supplyApple;不编译。
但是,正如方法supplyApple()的返回值表明Apple::new是Supplier<Apple>类型一样,为什么public static Supplier<Fruit> conFruit = Apple::new要编译。
发布于 2020-11-19 04:06:12
通过这样做:
public static Supplier<Fruit> conFruit = Apple::new;您正在Apple::new中创建一个多表达式。这些都是编译器在使用上下文中推断出来的。想想看:如果我只给你一个Apple::new,你能告诉我那是什么吗?一个Supplier?或者Provider (可能是这样的功能接口),等等?因此,这些类型是从所使用的周围上下文中得出的。就像编译器做的那样:
public static Supplier<Fruit> conFruit = (Supplier<Fruit>) () -> new Apple();这是完全合法的(这不是发生的事情,而是让你更容易理解)。
在另一个方法中,显式地告诉了返回类型是什么:
private static Supplier<Apple> supplyApple() {...}这是一个Supplier<Apple>。由于泛型是不变的,所以第二个赋值失败。
https://stackoverflow.com/questions/64898579
复制相似问题