Kann nicht in unspezifische verschachtelte Typen mit Generics umwandeln

8

Ich habe zwei Klassen mit verschachtelten Generika. Gibt es eine Möglichkeit, das

loszuwerden?

Typenkonflikt: Konvertierung von Msg<Value<String>> in Msg<Value<?>> Fehler nicht möglich? In der letzten Aufgabe

%Vor%     
stacker 26.08.2010, 13:46
quelle

5 Antworten

17

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).

Ein generischeres 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.

%Vor%

Hier ist eine andere Art, es anzuschauen:

  • Java-Generika sind typinvariant
  • Es gibt eine Umwandlung von Integer in Number , aber eine List< Integer > ist kein List< Number >
    • Analog dazu kann ein List<Integer> durch ein List<?> erfasst werden, aber a List< List<Integer> > ist kein List< List<?> >
  • Wenn Sie einen begrenzten Platzhalter verwenden, kann ein List<? extends  Number > einen List< Integer >
    • Ähnlich kann 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:

%Vor%

Verwandte Fragen

Siehe auch

polygenelubricants 26.08.2010, 14:06
quelle
3

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:

%Vor%     
ILMTitan 26.08.2010 14:14
quelle
3

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).

    
Ricky Clarkson 26.08.2010 15:40
quelle
1

Keine direkte Antwort, aber ich empfehle das Lesen von: Ссылка besser verstehe Generika.

    
Manuel Selva 26.08.2010 13:50
quelle
0

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%     
Peter DeWeese 26.08.2010 14:19
quelle

Tags und Links