Java-Container von generischen Typen
Ich bin auf eine Prüfung vorbereiten und einen der codes wurden wir von professor ist unklar für mich:
public class Z {
static java.util.LinkedList<? extends Object> a =
new java.util.LinkedList<String>();
public static void main(String[] args) {
a.add(null); //1
a.add(new Object()); //2
a.add("new Object()"); //3
System.out.println(a); //4
}
}
NetBeans gibt mir wirklich seltsame Zusammenstellung Fehler hier:
no suitable method found for add(java.lang.Object)
method java.util.LinkedList.add(capture#1 of ? extends java.lang.Object) is not applicable
(actual argument java.lang.Object cannot be converted to capture#1 of ? extends java.lang.Object by method invocation conversion)
no suitable method found for add(java.lang.String)
method java.util.LinkedList.add(capture#2 of ? extends java.lang.Object) is not applicable
(actual argument java.lang.String cannot be converted to capture#2 of ? extends java.lang.Object by method invocation conversion)
Könnte jemand bitte erklären Sie mir diese Fehler? Ich war mir ziemlich sicher, dass es möglich sein sollte, fügen Sie die String-Objekte zu dieser Liste.
- Ist das bedeutete zu sein "und Damen"? 😉
Du musst angemeldet sein, um einen Kommentar abzugeben.
PECS - Produzent extends, Consumer-super - das ist eine Eselsbrücke vorgeschlagen von Bloch zu bewältigen, die mit den oben genannten.
In anderen Worten, wenn Sie verwenden
extends
Sie können nur produzieren, Elemente aus Ihrer Sammlung. Wenn Sie möchten, es zu konsumieren-Elemente - verwendensuper
.Der Punkt ist, dass die Durchsetzung compile-time Sicherheit. Wenn Sie Ihre Sammlung definiert wurde, mit
? extends SomeBaseClass
würde dies bedeuten, dass "Es enthalten kann, die Instanzen einer Unterklasse der Basis-Klasse". In Ihrem Fall definieren Sienew LinkedList<String>()
, aber Sie versuchen, hinzufügen einerObject
- dies sollte nicht erlaubt werden, und es ist gefangen durch den compiler.a.add("new Object()");
als gut.Beim Aufruf
a.add()
, java kennt nur Sie Anruf hinzufügen, aufjava.util.LinkedList<? extends Object>
. Die verlinkte Liste mitString
ist unbekannt an dieser Stelle. Sie könnte Hinzugefügt haben einen anderen verlinkten Liste mit jeder anderen Art auf eine vorhergehende Zeile.Alle java weiß, ist, dass die Liste enthält etwas, das
extends Object
. Dies kann alles sein, da jede Klasse in java extends object.Beachten Sie, dass seit
a
enthalten kann, die verlinkten Liste, Sie kann nichts hinzufügen, um es. Wenn Sie fügen Sie eineObject
, die Liste ließe sich erwartenInteger
. Wenn Sie fügen Sie eineInteger
es könnte erwartet werden,Checksum
.Sie das gleiche problem haben ist Sie schreiben
dann:
Java immer noch nicht wissen, ob die Liste enthält Floats oder Integer-zahlen, so dass es zu verbieten beides.
Den richtigen Weg zu erklären, die Liste wäre:
Den folgenden code würde jetzt nicht:
weil
c
nicht enthaltenList<Integer>
nun, das hinzufügen einesFloat
gültig sein wird.Bearbeiten:
Um wieder auf das ursprüngliche Beispiel. Es ist eine etwas böse Art und Weise, wie die add-Funktion auf einem
List<? extends Object>
Hinweis 2 und 3 geben einen unchecked cast Warnung. Riskieren Sie heap pollution, in der Tat, Fall 2 macht genau das.
Was
LinkedList<? extends Object>
bedeutet "eine verknüpfte Liste, die enthalten kann, die nur Mitglieder bestimmter unbekannt Klasse, die Sie erweitertObject
", also ist es das gleiche wieLinkedList<?>
. Da es unbekannt die Klasse die man in Frage stellen, können Sie etwas hinzufügen, um eine solche Liste.Wenn Sie möchten, um eine Liste kann Elemente enthalten, die von alle - Klasse, verwenden
LinkedList<Object>
.Haben
LinkedList<? extends Object> a
die verknüpfte Liste nicht gebunden zu einer ArtT
da es die Wildcard zu einem unbekannt, erstreckt Objekt.Daher, wenn dabei
a.add()
, der parametrisierte Typ ist unbekannt und so übersetzt es alsa.add(null)
. Es Typen, die das unbekannte alsnull
. Es bedeutet, dass Sie nicht noch etwas hinzufügen zu dem unbekannten geben.Ihre
//1
akzeptabel ist (wie oben beschrieben), aber für//2
und//3
ist mehrdeutig.Der Grund für den Fehler ist, weil es versucht, eine Method Invocation Conversion an einen unbekannten Typ und da wir nicht wissen, die unbekannt, dass
extends
dieObject
es kann keine Konvertierung.LinkedList<? extends AnythingYouCanThinkOf> = new LinkedList<AnyClass>()
ich nur Liste erstellen, dass nichts Hinzugefügt werden kann??
. Wenn Sie möchten, um eine spezifische, verpflichtet Sie Ihre Liste zu einem Typ.