Java 供应商<TYPE>与供应商<? 扩展类型>



我知道这可能与泛型协变返回类型有关。但我撑不过去了。

给定Apple扩展Fruit的两个类。

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);
}
}

conFruitExtconFruit之间有什么不同?它们都是Apple的构造函数,调用get()可以创建苹果实例。

conFruitExt类型的额外? extends部分有什么不同吗?

更新1 2020/11/19

正如建议的答案所说,jonrsharpe在泛型中的问号,Supplier<Fruit>不编译为Suppier<Apple>,所以public static final Supplier<Fruit> supApple = TestReturnValue::supplyApple;不编译。

但由于方法supplyApple()的返回值表明Apple::newSupplier<Apple>的类型,public static Supplier<Fruit> conFruit = Apple::new为什么编译。它不是给Supplier<Fruit>分配了一个Supplier<Apple>实例吗?

这样做:

public static Supplier<Fruit> conFruit = Apple::new;

您正在Apple::new中创建poly表达式。这些是编译器在使用上下文中推断出来的。想想看:如果我只给你Apple::new,你能告诉我那是什么吗?Supplier?或者Provider(可能存在这样的功能接口(等等?因此,这些类型是从使用的周围环境中得出的。就像编译器做的那样:

public static Supplier<Fruit> conFruit = (Supplier<Fruit>) () -> new Apple();

这是完全合法的(这不是发生的事情,而是为了让你更容易理解(。

在另一种方法中,您已经明确地告诉了返回类型是什么:

private static Supplier<Apple> supplyApple() {...}

它是CCD_ 16。由于泛型是不变量,所以第二次赋值失败。

相关内容

  • 没有找到相关文章

最新更新