Verwenden Sie Folgendes:
%Vor% Das Problem besteht darin, dass die ?
in Msg<Value<?>> objMsg
NICHT für die Capture-Konvertierung geeignet ist. Es ist nicht "ein Msg
von Value
von einige Typen. Es ist" ein Msg
von Value
von ANY Typ ".
Dies erklärt auch, warum ich die Variable zusammen mit der Deklarationsänderung in someMsg
umbenannt habe. Das Value
kann nicht irgendein Object
sein. Es muss zum einigen -Typ gehören ( String
in diesem Beispiel).
Betrachten wir ein allgemeineres Beispiel für List<List<?>>
. Analog zum ursprünglichen Szenario kann ein List<List<?>>
NICHT ein List<List<Integer>>
einfangen-konvertieren.
Hier ist eine andere Art, es anzuschauen:
Integer
in Number
, aber eine List<
Integer
>
ist kein List<
Number
>
List<Integer>
durch ein List<?>
erfasst werden, aber a List<
List<Integer>
>
ist kein List<
List<?>
>
List<? extends
Number
>
einen List<
Integer
>
List<? extends
List<?>
>
eine List<
List<Integer>
erfassen und konvertieren >
Die Tatsache, dass einige ?
erfassen können und andere nicht, erklärt auch das folgende Snippet:
List<List<? extends Number>>
List<Animal> animals = new ArrayList<Dog>()
nicht tun kann? <E extends Number>
und <Number>
? Obwohl Ihr generischer Typparameter einen Platzhalter enthält, ist er selbst kein Platzhalter. Bei der Zuweisung an eine Variable ( Msg<T>
) mit einem generischen Typ ohne Platzhalter T
muss das zugewiesene Objekt genau den Datentyp T
als generischen Typ haben (einschließlich aller generischen Typparameter T
, Wildcard und nicht Platzhalter). In Ihrem Fall T
ist Value<String>
, was nicht der gleiche Typ wie Value<?>
ist.
Was Sie tun können, weil Value<String>
zu Value<?>
zuweisbar ist, verwenden Sie den Platzhalter:
Meine Antwort ähnelt der anderen, ist aber hoffentlich klarer.
%Vor%Letzteres kann nicht in ersteres konvertiert werden, da Sie dann eine List & lt; Number & gt; zu Ihrer List & lt; List & lt; String & gt; & gt ;; die klar zu knacken wäre.
Beachten Sie, dass sich die Regeln dafür nicht ändern, wenn Sie List durch einen Typ ersetzen, der nicht .add enthält. Java würde dafür eine Deklarations-Site-Kovarianz und / oder Kontravarianz benötigen (wie C # IEnumerable & lt; out T & gt; oder Scala's List [+ A]). Java hat nur die Kovarianz und die Kontravarianz der Benutzungsorte (? Erweitert X,? Super X).
Keine direkte Antwort, aber ich empfehle das Lesen von: Ссылка besser verstehe Generika.
ILMTitan hat eine gute Lösung, und wenn Sie die Klasse nicht für Value definieren möchten, können Sie statt der Generika jetzt auch den Basistyp verwenden, da Sie dort eine Sicherheitsfunktion ausschalten ist weg. Sie können möglicherweise sogar einen Parameter übergeben, um diese Methode generischer zu machen, aber der Schlüssel ist "@SuppressWarnings".
%Vor%