好吧,这并不是说Java7很乐意运行它。在给出错误之前,它会给出几个警告:
jatin@jatin-~$ javac -Xlint:unchecked -source 1.7 com/company/Main.java
warning: [options] bootstrap class path not set in conjunction with -source 1.7
com/company/Main.java:19: error: no suitable method found for set(Derived,Base)
set(new Derived(), new Consumer().get());
^
method Consumer.set(Base,Derived) is not applicable
(argument mismatch; Base cannot be converted to Derived)
method Consumer.set(Derived,Collection<? extends Consumer>) is not applicable
(argument mismatch; Base cannot be converted to Collection<? extends Consumer>)
com/company/Main.java:28: warning: [unchecked] unchecked cast
return (T) new Derived();
^
required: T
found: Derived
where T is a type-variable:
T extends Base declared in method <T>get()
问题是这样的:
set(new Derived(), new Consumer().get());
当我们这样做时,如果我们看一下 的签名。它返回我们一个 类型 。我们知道,这以某种方式扩展了.但我们不知道具体是什么。它可以是任何东西。因此,如果我们不能具体决定什么是,那么编译器如何呢?new Consumer().get()
get
T
T
Base
T
T
告诉编译器的一种方法是通过硬编码并具体通过以下方式告诉它:。set(new Derived(), new Consumer().<Derived>get());
上面的原因是极其极端(故意重复)危险的,是当你尝试这样做时:
class NewDerived extends Base {
public String getName(){return "name";};
}
NewDerived d = new Consumer().<NewDerived>get();
System.out.println(d.getName());
在Java7(或任何Java版本)中,它将在运行时引发异常:
线程“main” java.lang.ClassCastException 中的异常:com.company.Derived 不能强制转换为 com.company.NewDerived
因为返回一个类型的对象,但您已向编译器提及它是 .而且它不能正确地将 Derived 转换为 NewDerived。这就是它显示警告的原因。get
Derived
NewDerived
根据错误,现在我们了解了 出了什么问题。它的类型是 .执行 查找将参数作为 的方法。new Consumer().get()
something that extends base
set(new Derived(), new Consumer().get());
Derived (or any super class of it), something that extends Base
现在,您的两种方法都符合第一个参数的条件。根据第二个参数,两者都有资格,因为某些东西可以被派生或扩展派生或扩展集合。这就是 Java8 抛出 Error 的原因。something that extends base
根据Java7,它的类型推断有点弱。所以它尝试做类似的事情,
Base base = new Consumer().get();
set(new Derived(), base);
同样,它找不到作为论据的正确方法。因此,它抛出错误,但出于不同的原因:Derived, Base
set(new Derived(), new Consumer().get());
^
method Consumer.set(Base,Derived) is not applicable
(argument mismatch; Base cannot be converted to Derived)
method Consumer.set(Derived,Collection<? extends Consumer>) is not applicabl e
(argument mismatch; Base cannot be converted to Collection<? extends Consu mer>)
PS:感谢Holger指出我的答案不完整。