好吧,这似乎不是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 get()
问题是这样的:
set(new Derived(), new Consumer().get());
当我们做的时候new Consumer().get(),如果我们看签名get。它返回一个Type T。我们知道T某种程度上可以扩展Base。但是我们不知道T具体是什么。可以是任何东西。因此,如果我们不能明确决定是什么T,那么编译器又如何呢?
告诉编译器的一种方式,是硬编码,并通过明确告诉它:set(new Derived(), new Consumer().get());。
尝试执行此操作时,上述原因极为危险(有意重复):
class NewDerived extends Base {
public String getName(){return "name";};
}
NewDerived d = new Consumer().get();
System.out.println(d.getName());
在Java7(或任何Java版本)中,它将在运行时引发异常:
线程“主”中的异常java.lang.ClassCastException:com.company.Derived无法转换为com.company.NewDerived
因为get返回类型的对象,Derived但是您向编译器提到了它的类型NewDerived。它不能正确地将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。
现在,您的两个方法都符合第一个参数的条件。根据第二个参数something that extends base,两者都符合条件,因为某些东西可以派生或扩展Derived或扩展Collection。这就是Java8引发Error的原因。
按照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指出我的答案不完整。