1. Einfaches Verständnis von Generika
Generics sind eine neue Funktion von Java SE 1.5. Der Kern von Generics ist ein parametrisierter Typ, was bedeutet, dass der Datentyp, mit dem gearbeitet wird, als Parameter angegeben wird. Der beliebte Punkt ist „Typvariable“. Variablen dieses Typs können bei der Erstellung von Klassen, Schnittstellen und Methoden verwendet werden.
Der einfachste Weg, Java-Generika zu verstehen, besteht darin, sie als praktische Syntax zu betrachten, die Ihnen einige Java-Casting-Vorgänge erspart:
Kopieren Sie den Code wie folgt: List<Apple> box = new ArrayList<Apple>();box.add(new Apple());Apple apple =box.get(0);
Der obige Code selbst drückt sich sehr deutlich aus: Box ist eine Liste mit Apple-Objekten. Die get-Methode gibt eine Apple-Objektinstanz zurück und in diesem Prozess ist keine Typkonvertierung erforderlich. Ohne Generika muss der obige Code wie folgt geschrieben werden:
Kopieren Sie den Code wie folgt: Apple apple = (Apple)box.get(0);
2. Die Peinlichkeit von Generika
Der größte Vorteil von Generika besteht darin, dass sie Programmtypsicherheit bieten und abwärtskompatibel sind, aber sie haben auch einen unangenehmen Punkt: Der Typ des Generikums muss bei jeder Definition angegeben werden. Es fühlt sich nicht nur etwas ausführlich an um es explizit anzugeben, aber es ist auch so, dass viele Programmierer mit Generika nicht vertraut sind und daher oft nicht in der Lage sind, korrekte Typparameter bereitzustellen. Jetzt kann der Compiler automatisch auf die Parametertypen von Generika schließen, was solche Situationen reduzieren und den Code verbessern kann Lesbarkeit.
3. Verbesserungen bei der generischen Typinferenz in Java 7
Wenn Sie in früheren Versionen generische Typen verwenden, müssen Sie beim Deklarieren und Zuweisen von Werten den generischen Typ auf beiden Seiten hinzufügen. Zum Beispiel:
Kopieren Sie den Code wie folgt: Map<String, String> myMap = new HashMap<String, String>();
Sie denken vielleicht: Ich habe den Parametertyp bereits beim Deklarieren der Variablen angegeben. Warum muss ich ihn beim Initialisieren des Objekts erneut angeben? Glücklicherweise wurde diese Methode in Java SE 7 verbessert, und jetzt können Sie Werte mithilfe der folgenden Anweisungen deklarieren und zuweisen:
Kopieren Sie den Code wie folgt: Map<String, String> myMap = new HashMap<>(); //Achten Sie auf das „<>“ am Ende
In dieser Anweisung leitet der Compiler automatisch den generischen Typ ab, wenn er HashMap basierend auf dem generischen Typ instanziiert, wenn die Variable deklariert wird. Achten Sie auch hier unbedingt auf das „<>“ nach der neuen HashMap. Nur das Hinzufügen dieses „<>“ bedeutet eine automatische Typinferenz. Andernfalls handelt es sich um eine nicht generische HashMap, die bei Verwendung des Compilers angegeben wird Kompilieren Sie den Quellcode.
Allerdings: Die Typinferenz von Java SE 7 beim Erstellen generischer Instanzen ist begrenzt: Nur wenn der parametrisierte Typ des Konstruktors explizit im Kontext deklariert wird, kann die Typinferenz verwendet werden, andernfalls funktioniert sie nicht. Beispiel: Das folgende Beispiel kann in Java 7 nicht korrekt kompiliert werden (aber es kann jetzt in Java 8 kompiliert werden, da der Typ des Generikums automatisch basierend auf den Methodenparametern abgeleitet wird):
Kopieren Sie den Codecode wie folgt:
List<String> list = new ArrayList<>();
list.add("A");// Da addAll einen Parameter vom Typ Collection<? erweitert String> erwartet, kann die folgende Anweisung nicht übergeben werden
list.addAll(new ArrayList<>());
4. Verbesserungen bei der generischen Typinferenz in Java 8
Es gibt zwei Haupttypen der Zieltypinferenz für Generika in Java 8:
1. Unterstützung der Ableitung generischer Zieltypen über den Methodenkontext
2. Unterstützt die Übergabe einer generischen Typinferenz an die letzte Methode in der Methodenaufrufkette.
Schauen wir uns ein Beispiel von der offiziellen Website an:
Kopieren Sie den Codecode wie folgt:
Klasse List<E> {
static <Z> List<Z> nil() { ... };
static <Z> List<Z> cons(Z head, List<Z> tail) { ... };
E head() { ... }
}
Gemäß den Eigenschaften von JEP101 können wir beim Aufruf der obigen Methode so schreiben
Kopieren Sie den Codecode wie folgt:
// Den Typ des Generikums automatisch über den Zielparameter der Methodenzuweisung ableiten
List<String> l = List.nil();
//Anstelle des angegebenen Typs angezeigt
//List<String> l = List.<String>nil();
// Den Typ des Generikums anhand des vorherigen Methodenparametertyps ableiten
List.cons(42, List.nil());
//Anstelle des angegebenen Typs angezeigt
//List.cons(42, List.<Integer>nil());
5. Zusammenfassung
Das Obige ist der Funktionsinhalt von JEP101. Als Vertreter statischer Sprachen kann gesagt werden, dass Java über ein Rich-Type-System verfügt. Das Problem der Konvertierung zwischen Typen bereitet jedem Java-Programmierer Probleme. Das automatische Ableiten von Typen durch den Compiler kann das Problem einer zu komplexen Typkonvertierung etwas lindern. Obwohl es eine kleine Verbesserung ist, wird es definitiv große Auswirkungen auf unsere Programmierer haben, die jeden Tag Code schreiben. Zumindest werden sie sich glücklicher fühlen ~~ Vielleicht werden wir in Java 9 eine universelle Typvariable wie js oder einige dynamische Sprachen bekommen von scala sind so^_^