Mehrere Platzhalter für generische Methoden: Ein Java-Compiler-Rätsel
Einführung
In Java-Generika , Platzhalter (*) stehen für unbekannte Typen. Wenn bei generischen Methoden mehrere Platzhalter verwendet werden, kann dies zu Verwirrung und unerwartetem Verhalten führen. Dieser Artikel untersucht die Komplexität mehrerer Platzhalter und ihre Auswirkungen auf die Typsicherheit von Java.
Die Verwirrung
Bedenken Sie den folgenden Code:
public class TwoListsOfUnknowns { static void doNothing(List<?> list1, List<?> list2) { } public static void main(String[] args) { List<String> list1 = null; List<Integer> list2 = null; doNothing(list1, list2); // compiles fine! } }
Die beiden Platzhalter in doNothing scheinen nichts miteinander zu tun zu haben, sodass Sie es mit einem List
static void doSomethingIllegal(List<?> list1, List<?> list2) { list1.addAll(list2); // DOES NOT COMPILE!!! }
Dies deutet darauf hin, dass list1 und list2 zwar unterschiedliche Typen sein können, aber möglicherweise eine Verbindung haben, die eine direkte Verwendung verhindert.
Die Verwirrung durch verschachtelte Platzhalter
Weitere Untersuchungen zeigen, dass die Verwirrung nicht in mehreren Platzhaltern, sondern in verschachtelten Platzhaltern liegt Platzhalter:
public class LOLUnknowns1 { static void probablyIllegal(List<List<?>> lol, List<?> list) { lol.add(list); // this compiles!! how come??? } }
Dieser Code lässt sich fehlerfrei kompilieren, auch wenn die Liste einen anderen Typ als die Elemente von lol haben könnte. Es ist jedoch wichtig zu beachten, dass dieses Szenario Fragen zur Typsicherheit aufwirft.
Die Wahrheit: Capture-Konvertierung
Die Verwirrung entsteht durch ein Konzept namens Capture-Konvertierung. Es ermöglicht bestimmten Platzhaltern, bestimmte Typen zu erfassen, wenn sie in generischen Methoden verwendet werden. Aus diesem Grund wird die folgende Variante von „wahrscheinlich illegal“ kompiliert:
static void probablyIllegalAgain(List<List<? extends Number>> lol, List<? extends Number> list) { lol.add(list); // compiles fine!!! how come??? }
Hier kann der Platzhalter in lol einen Typ erfassen, der Number erweitert, wie z. B. List
Verschachtelte Platzhalter verstehen
Die wichtigste Erkenntnis ist, dass mehrere Platzhalter selbst kein Problem darstellen. Die Verwirrung entsteht, wenn versucht wird, einen verschachtelten Platzhalter zu verwenden, um einen Typ zu erfassen, der aufgrund von Typabweichungen nicht „kompatibel“ ist.
Im Fall von LOLUnknowns1 ist der verschachtelte Platzhalter in List> kann einen bestimmten Typ nicht erfassen, da die Erfassung nicht für alle möglichen Elementtypen von lol sicher wäre. Aus diesem Grund kann eine Liste von beliebigem Typ sein, was zu potenziellen Problemen mit der Typsicherheit führen kann.
Fazit
Mehrere Platzhalter bei generischen Methoden können verwirrend sein, aber das Verständnis der Capture-Konvertierung und seine Grenzen sind entscheidend. Verschachtelte Platzhalter müssen sorgfältig geprüft werden, um die Typsicherheit zu gewährleisten. Durch die Einhaltung dieser Prinzipien können Sie sich in den Feinheiten der Java-Generika zurechtfinden und robusten Code schreiben.
Das obige ist der detaillierte Inhalt vonWarum führen mehrere Platzhalter bei generischen Methoden in Java zu Verwirrung?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!