Ich bin auf etwas gestoßen, das ich in Java seltsam finde und ich konnte nicht viele Informationen darüber finden. Betrachten Sie den folgenden Code:
%Vor% Der Compiler zeigt einen Fehler in der Methode getMap()
:
Aber derselbe Fehler ist nicht für die Methode getList()
vorhanden, aber ich würde erwarten, dass entweder beide funktionieren oder beide fehlschlagen. In beiden Fällen delegiert die übergeordnete Methode List<String>
anstelle von List<? extends Object>
. Kann jemand das erklären?
Dies liegt daran, dass eine implizite Konvertierung von List<String>
zu List<? extends Object>
existiert, aber nicht von Map<Long, List<String>>
zu Map<Long, List<? extends Object>>
.
Alle generischen Typen sind invariant, sofern Sie keine Platzhalter verwenden. Da in den generischen Argumenttypen des "äußeren" Map-Typs kein Platzhalter vorhanden ist, kann kein generischer Typ erfasst werden, der nicht genau übereinstimmt.
Wenn Ihr Kartentyp Map<Long, ? extends List<? extends Object>>
wäre, dann würde es wie erwartet funktionieren.
Und der andere Teil, wenn die Antwort ist, dass Unterklassen eine Supertype-Methode mit einem anderen Rückgabetyp überschreiben oder implementieren können, aber nur, wenn der Rückgabetyp der Methode des Untertyps implizit in den Rückgabetyp der Supertypemethode konvertiert werden kann. (In Java 1.4 und darunter würde sogar das nicht funktionieren: Es wäre ein Kompilierzeitfehler, wenn die Typen nicht genau übereinstimmen würden.)