Heim  >  Artikel  >  Java  >  Warum können wir generische Typparameter in Java nicht mit „super“ binden?

Warum können wir generische Typparameter in Java nicht mit „super“ binden?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-10-31 10:42:29984Durchsuche

Why Can't We Bound Generic Type Parameters with 'super' in Java?

Generika mit „super“ begrenzen: Eine Erklärung

Bei der Arbeit mit Generika in Java ist es oft notwendig, Typparameter zu binden, um die Kompatibilität mit bestimmten Typen sicherzustellen. Mit dem Schlüsselwort „super“ kann angegeben werden, dass ein Typparameter eine Superklasse oder Superschnittstelle eines angegebenen Typs sein muss. Diese Verwendung ist jedoch nur mit Platzhaltern zulässig, nicht mit Typparametern.

In der Collection-Schnittstelle wird die toArray-Methode wie folgt deklariert:

<T> T[] toArray(T[] a);

Mit dieser Methode können Sie eine Sammlung konvertieren von Elementen vom Typ „T“ in ein Array von Elementen desselben Typs. Sie können die Methode jedoch nicht wie folgt schreiben:

<T> <S super T> S[] toArray(S[] a);

Der Grund dafür ist, dass das Schlüsselwort „super“ in Generics zum Binden von Platzhaltern und nicht für Typparameter verwendet wird. Im obigen Beispiel versuchen Sie, mit „super“ den Typparameter „S“ so zu binden, dass er eine Superklasse oder Superschnittstelle von „T“ ist. Diese Verwendung ist nicht zulässig, da sie möglicherweise zu Problemen mit der Typsicherheit führen könnte.

Betrachten Sie beispielsweise den folgenden Code:

List<Integer> integerList = new ArrayList<>();
Integer[] integerArray = new Integer[5];
Number[] numberArray = new Number[5];
Object[] objectArray = new Object[5];
// hypothetical method
integerList.toArray(super T numberArray)

Gemäß Ihrer vorgeschlagenen Syntax würde der obige Code Folgendes zulassen Folgende Typzuweisungen:

integerList.toArray(super T integerArray)  // compiles fine!
integerList.toArray(super T numberArray)   // compiles fine!
integerList.toArray(super T objectArray)  // compiles fine!

Da „String“ jedoch keine Oberklasse von „Integer“ ist, sollte der folgende Code nicht kompiliert werden:

integerList.toArray(super T stringArray)  // should not compile

Aber noch einmal, da „Object ' eine Oberklasse von 'Integer' und 'String' ist, würde der folgende Code trotzdem kompiliert werden, auch wenn er zur Laufzeit eine 'ArrayStoreException' auslösen würde:

integerList.toArray(super T stringArray)  // compiles fine!

Dieses Verhalten ist unerwünscht, da es dazu führen könnte zur Eingabe von Sicherheitsverstößen. Um dies zu verhindern, erlaubt Java die Verwendung von „super“ zum Binden von Typparametern nicht. Stattdessen können Sie „super“ nur zum Binden von Platzhaltern verwenden.

Sie könnten beispielsweise die toArray-Methode wie folgt mit einem Platzhalter umschreiben:

<T> T[] toArray(T[] a);

Mit dieser Methode können Sie Code schreiben das ist sowohl typsicher als auch flexibel. Beispielsweise wird der folgende Code kompiliert und löst zur Laufzeit keine „ArrayStoreException“ aus:

List<Integer> integerList = new ArrayList<>();
Integer[] integerArray = new Integer[5];
Number[] numberArray = new Number[5];
Object[] objectArray = new Object[5];

integerList.toArray(objectArray);

Das obige ist der detaillierte Inhalt vonWarum können wir generische Typparameter in Java nicht mit „super“ binden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn