Java kann häufig auf Basis der Argumente (und sogar auf dem Rückgabetyp im Gegensatz zu beispielsweise C#) auf Generika schließen.Geerbte Platzhaltergenerika im Rückgabetyp
Typischer Fall: Ich habe eine generische Klasse Pair<T1, T2>
bekam, die nur ein paar Werte speichert und kann auf folgende Weise verwendet werden:
Pair<String, String> pair = Pair.of("Hello", "World");
Die Methode of
sieht genauso aus wie folgt aus:
public static <T1, T2> Pair<T1, T2> of(T1 first, T2 second) {
return new Pair<T1, T2>(first, second);
}
Sehr schön. Allerdings ist dies nicht mehr funktioniert für die folgenden Anwendungsfall, die Platzhalter erfordert: (. Beachten Sie die explizite Umwandlung List.class
den richtigen Typ zu machen)
Pair<Class<?>, String> pair = Pair.of((Class<?>) List.class, "hello");
Der Code schlägt mit dem folgenden Fehler (vorausgesetzt von Eclipse):
AllerdingsTypenkonflikt: kann nicht von
TestClass.Pair<Class<capture#1-of ?>,String>
zuTestClass.Pair<Class<?>,String>
konvertieren
, expliziten Aufruf der Konstruktor funktioniert immer noch wie erwartet:
Pair<Class<?>, String> pair =
new Pair<Class<?>, String>((Class<?>) List.class, "hello");
Kann jemand dieses Verhalten erklären? Ist es von Entwurf? Ist es gesucht? Mache ich etwas falsch oder bin ich auf einen Fehler im Design/Bug des Compilers gestoßen?
wilde Vermutung: die „capture # 1-of?“ Scheint irgendwie zu implizieren, dass der Platzhalter wird vom Compiler on the fly ausgefüllt, die Art machte ein Class<List>
und damit sie nicht die Umwandlung (Pair<Class<?>, String>
-Pair<Class<List>, String>
) . Ist das richtig? Gibt es eine Möglichkeit, dies zu umgehen?
Der Vollständigkeit halber, hier ist eine vereinfachte Version der Pair
Klasse:
public final class Pair<T1, T2> {
public final T1 first;
public final T2 second;
public Pair(T1 first, T2 second) {
this.first = first;
this.second = second;
}
public static <T1, T2> Pair<T1, T2> of(T1 first, T2 second) {
return new Pair<T1, T2>(first, second);
}
}
Es sieht so aus, als ob der Konverter die Signatur von "of" sieht, wenn er ein Paar zurückgibt erweitert Klasse,? erweitert Klasse > Typ. Für die letzten Klassen scheint es schlau genug zu sein, den extend-Teil zu reduzieren, deshalb beschweren sie sich nicht über den String. –
Zed
Hmmm, interessant. Danke, dass du mich hier verlinkt hast. – jjnguy
Es funktioniert jetzt in Java8. Der Zieltyp wird auch für die Inferenz herangezogen. – ZhongYu