Nun, es ist nicht so, als wäre Java7 glücklich, es zu betreiben.Es gibt einige Warnungen vor den Fehler geben:
[email protected]~$ 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()
Das Problem ist folgendes:
set(new Derived(), new Consumer().get());
Wenn wir das tun new Consumer().get()
, wenn wir bei Unterzeichnung get
aussehen. Es gibt uns einen Typ T
zurück. Wir wissen, dass T
irgendwie erweitert Base
. Aber wir wissen nicht, was T
speziell ist. Es kann alles sein. Also, wenn wir nicht genau entscheiden können, was T
ist, dann wie kann Compiler?
Eine Möglichkeit, den Compiler zu unterscheiden, ist das Hardcoding und das genaue Abgeben von: set(new Derived(), new Consumer().<Derived>get());
.
Die oben genannten Grund ist extrem extrem (wiederholt absichtlich) gefährlich ist, wenn Sie versuchen, diese zu tun:
class NewDerived extends Base {
public String getName(){return "name";};
}
NewDerived d = new Consumer().<NewDerived>get();
System.out.println(d.getName());
In Java7 (oder jede Java-Version), wird es Ausnahme zur Laufzeit werfen:
Exception in thread "main" java.lang.ClassCastException: com.company.Derived cannot be cast to com.company.NewDerived
Weil get
ein Objekt vom Typ Derived
zurückgibt, aber Sie haben zum Compiler erwähnt, dass es von NewDerived
ist. Und er kann Derived nicht zu NewDerived konvertieren. Aus diesem Grund wird eine Warnung angezeigt.
Gemäß dem Fehler, jetzt verstehen wir, was mit new Consumer().get()
falsch ist. Es ist Typ something that extends base
. Doing set(new Derived(), new Consumer().get());
sucht nach einer Methode, die Argumente als Derived (or any super class of it), something that extends Base
akzeptiert.
Jetzt sind beide Methoden für das erste Argument geeignet. Nach dem zweiten Argument something that extends base
, wieder beide sind als geeignet, dass etwas abgeleitet werden kann oder erweitert oder erweitern Sammlung. Aus diesem Grund gibt Java8 Fehler aus.
Gemäß Java7 ist die Art der Inferenz etwas schwächer. So versucht sie, etwas zu tun, ähnlich,
Base base = new Consumer().get();
set(new Derived(), base);
Und wieder kann es nicht die richtige Methode finden, die Derived, Base
als Argument nimmt. Daher wirft es Fehler aber aus unterschiedlichen Gründen:
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: Danke an Holger, für Unvollständigkeit meiner Antwort darauf hingewiesen.
Nun, es kompiliert für mich gut mit Java 8 – Dici
Eclipse kompiliert dies, aber 'javac' kann nicht. Ist es sicher anzunehmen, dass Sie 'javac' verwenden? – Jeffrey
@ Jeffrey Ja. Ich bekomme diesen Fehler Kompilierung von der Kommandozeile mit javac und mit IntelliJ. Ich bin mit Java-Version 1.8.0_25 –