ListT ist nicht gleich ListT?

8

Sehen Sie sich dieses einfache Beispiel für Java-Generics an:

%Vor%

Es wird ein Fehlerkompiliervorgang ausgeführt, der behauptet, dass die Typen inkompatibel sind, behauptet jedoch, dass die beiden Variablen vom selben Typ sind:

%Vor%

Wenn ich die erste Zeile von length () in List<T> l = (List<T>)(Object)this.l; ändere, funktioniert es. Warum?

    
Dog 24.06.2013, 18:31
quelle

1 Antwort

19

Sie haben eine generische Methode in einer generischen Klasse mit dieser Zeile deklariert:

%Vor%

Diese <T> unterscheidet sich von der <T> Ihrer Klasse. Nach dem JLS Abschnitt 6.3 :

  

Der Geltungsbereich des Typparameters einer Klasse (§8.1.2) ist der Typparameter   Abschnitt der Klassendeklaration, der Typ Parameterabschnitt von jedem   Superklasse oder Superschnittstelle der Klassendeklaration und der Klasse   Körper.

Sie müssen <T> für Ihre Methode nicht erneut deklarieren. Der Typparameter der Klasse ist bereits im Bereich.

Um den generischen Typparameter <T> Ihrer Klasse zu verwenden, muss Ihre Methode keine weitere <T> deklarieren und einfach die <T> Ihrer Klasse verwenden:

%Vor%

Um zu verstehen, warum Ihr Casting funktioniert:

%Vor%

Sie können jedes Objekt in Object umwandeln. Dann werfen Sie das Ergebnis auf List<T> . Du kannst es immer auf alles übertragen, was du willst. Java wirft zur Laufzeit einfach ClassCastException , wenn es zur Laufzeit nicht wirklich ein List war. Aber der Compiler wird auch warnen, dass er ungeprüfte oder unsichere Operationen verwendet, weil er nicht garantieren kann, dass diese <T> die ursprüngliche <T> ist.

Um den Unterschied zwischen <T> s zu veranschaulichen, können Sie <U> als generischen Typparameter für die Methode verwenden und die gleichen Ergebnisse erhalten:

%Vor%

Dies wird mit der gleichen Art von Sicherheitswarnung kompiliert.

Wenn Sie wirklich wissen, dass Typsicherheit garantiert werden kann, können Sie @SuppressWarnings("unchecked") verwenden, um Ihre Methode zu kommentieren. Aber hier würde ich immer noch den generischen Typparameter vollständig aus der Methode entfernen und den Typparameter der Klasse verwenden.

    
rgettman 24.06.2013, 18:32
quelle

Tags und Links