Ich habe diesen Code, die, wenn sie als Java 7 (Eclipse-Compiler) kompiliert fein kompiliert, aber nicht, wenn ich die Projekteinstellungen auf Java 8 gesetzt:Wildcard in Generika verhalten sich unterschiedlich in Java 7 und 8
package scratch;
class Param<T extends Comparable<T>> {
public Comparable<?> get() {
return null;
}
}
public class Condition<T extends Comparable<T>> {
public static <T extends Comparable<T>> Condition<T> isInRange(T lower, T upper) {
return null;
}
public void foo() {
Comparable bound = null; // Line 15
Param<?> param = new Param<Double>();
Condition.isInRange(param.get(), bound); // Line 17
}
}
In Java 7, bekomme ich diese Warnungen:
- Zeile 15: Vergleichbar ist ein roher Typ. Typ Sicherheit: Verweise auf generische Art Vergleichbare sollten
- Linie 17 parametriert werden Ungeprüfter Aufruf isInRange (Comparable, vergleichbar) der generischen Methode isInRange (T, T) vom Typ Zustand
Wenn ich <?>
in Zeile hinzufügen 15, wird die Warnung gegangen, aber ich dann einen Fehler in Zeile 17 erhalten:
Bound Mismatch: die generische Methode isInRange (T, T) vom Typ Zustand ist nicht anwendbar für die Argumente (Comparable, vergleichbar). Der abgeleitete Typ Vergleichbar ist kein gültiger Ersatz für die beschränkte Parameter>
Weiß jemand, was genau diese Inkompatibilität verursacht?
PS: ich diese hässlichen Abgüsse hinzugefügt, um den Code zu kompilieren unter beiden Versionen von Java zu machen:
Condition.isInRange((Comparable)param.get(), (Comparable) bound);
Der Eclipse-Compiler hat einige Bugs in Bezug auf Generics, also sollten Sie mit 'javac' testen. – Kayaman
Das hat nichts mit dem Platzhalter zu tun, sondern mit dem * rohen Typ * der 'gebundenen' Variablen. In Java-7 werden dadurch alle Prüfungen zum Methodenaufruf 'isInRange' ausgeschaltet. In Java-8 erkennt die Zieltypisierung immer noch die Ungültigkeit des verschachtelten Aufrufs, ähnlich wie in diesem Szenario (http://stackoverflow.com/a/26285613/2711488). Ich verstehe nicht, warum du denkst, dass dein Typ, der zum rohen 'Komparator' umgewandelt wird, hässlicher ist als die anfängliche Verwendung des Rohtyps. Natürlich ist die zweite Art der Besetzung unsinnig, da 'gebunden 'bereits ein rohes' Vergleichbares 'ist. – Holger
@Kayaman: In diesem Fall ist Eclipse perfekt im Einklang mit 'javac'. – Holger