Heim Java javaLernprogramm Detaillierte Erläuterung der Java-Generika

Detaillierte Erläuterung der Java-Generika

Dec 19, 2016 pm 02:58 PM
泛型

  1. Übersicht
    Vor der Einführung von Generika wurden Java-Typen in primitive Typen und komplexe Typen unterteilt. Komplexe Typen wurden in Arrays und Klassen unterteilt. Nach der Einführung von Generika kann ein komplexer Typ
    in weitere Typen unterteilt werden.
    Zum Beispiel ist der ursprüngliche Typ List jetzt in List, List unterteilt.
    Beachten Sie, dass List jetzt zwei verschiedene Typen sind.
    Es besteht keine Vererbungsbeziehung zwischen ihnen, auch wenn String Object erbt. Der folgende Code ist illegal:
    List ls = new ArrayList();
    List Der Compiler ermöglicht das Hinzufügen beliebiger Objekte (z. B. Integer) zu lo, aber dieses Objekt ist
    List, wodurch die Integrität des Datentyps zerstört wird.
    Wenn Sie möchten, dass die Methoden in der Klasse mehrere Datentypen unterstützen, müssen Sie vor der Einführung von Generika die Methoden überladen. Nach der Einführung von Generika kann dieses Problem gelöst werden (Polymorphismus) und Sie können mit der Definition fortfahren Beziehungen zwischen mehreren Parametern und Rückgabewerten.
    Zum Beispiel:
    public void write(Integer i, Integer[] ia);
    public void write(Double d, Double[] da); Die generische Version von
    ist
    public void write(T t, T[] ta);

    2. Definieren und verwenden Sie den Namensstil der Typparameter:
    Es wird empfohlen, prägnante Namen zu verwenden die Namen formaler Typparameter (möglichst ein einzelnes Zeichen). Vermeiden Sie am besten Kleinbuchstaben, da dies die Unterscheidung von anderen gewöhnlichen formalen
    -Parametern erleichtert.
    Verwenden Sie T zur Darstellung des Typs, wenn es keinen spezifischeren Typ zur Unterscheidung gibt. Dies wird häufig bei generischen Methoden beobachtet. Wenn mehrere Typparameter vorhanden sind,
    verwenden wir möglicherweise einen Buchstaben in der Nähe von T im Alphabet, z. B. S.
    Wenn eine generische Funktion innerhalb einer generischen Klasse erscheint, ist es am besten, die Verwendung desselben Namens im Typparameter der Methode und im Typparameter der Klasse zu vermeiden, um Verwirrung zu vermeiden
    . Das Gleiche gilt für innere Klassen.

    2.1 Definieren Sie eine Klasse mit Typparametern
    Geben Sie beim Definieren einer Klasse mit Typparametern im Feld <> direkt nach dem Klassennamen den Namen eines oder mehrerer Typparameter an Beschränken Sie den
    -Wertebereich von Typparametern und trennen Sie mehrere Typparameter durch ein Vorzeichen.
    Nach der Definition von Typparametern können Sie Typparameter fast überall in der Klasse nach der Definitionsposition verwenden (außer statische Blöcke, statische Eigenschaften, statische Methoden),
    genau wie bei der Verwendung gewöhnlicher Typen.
    Beachten Sie, dass von der übergeordneten Klasse definierte Typparameter nicht von der Unterklasse geerbt werden können.
    öffentliche Klasse TestClassDefine Geben Sie im <> unmittelbar nach der Änderung des sichtbaren Bereichs den Namen eines oder mehrerer Typparameter an per Zeichen.
    Nachdem Sie die Typparameter definiert haben, können Sie die Typparameter an einer beliebigen Stelle in der Methode nach der Definitionsposition verwenden, genau wie bei der Verwendung gewöhnlicher Typen.
    Zum Beispiel:
    public Der Hauptzweck von Ride besteht darin, die Beziehung zwischen mehreren Parametern und Rückgabewerten auszudrücken. Beispielsweise ist in der
    -Vererbungsbeziehung zwischen T und S in diesem Beispiel der Typ des Rückgabewerts derselbe wie der Wert des ersten Typparameters.
    Wenn Sie nur Polymorphismus erreichen möchten, verwenden Sie bitte zuerst Platzhalter. Platzhalterinhalte finden Sie im folgenden Abschnitt.
    public void testGenericMethodDefine2(List s){
    ...
    }
    sollte in
    public void testGenericMethodDefine2(List s){ geändert werden
    ...
    }

    3. Typparameterzuweisung
    Beim Zuweisen von Werten zu Typparametern einer Klasse oder Methode müssen alle Typparameter zugewiesen werden. Andernfalls erhalten Sie einen Kompilierungsfehler.

    3.1 Zuweisen von Typparametern zu einer Klasse mit Typparametern
    Es gibt zwei Möglichkeiten, einer Klasse Typparameter mit Typparametern zuzuweisen
    Erstens, wenn eine Klassenvariable deklariert oder instanziiert wird. Beispiel:
    List list;
    list = new ArrayList;
    wenn die zweite geerbte Klasse oder die Schnittstelle implementiert. Beispielsweise implementiert
    die öffentliche Klasse MyList List 3.2 Zuweisen von Werten zu Methoden mit Typparametern
    , Kompilieren Der Compiler weist Typparametern automatisch Werte zu. Wenn die Zuweisung nicht erfolgreich ist, wird ein Kompilierungsfehler gemeldet. Zum Beispiel
    public T testGenericMethodDefine3(T t, List list){
    ...
    }
    public testGenericMethodDefine4(List list2 ){
    ...
    }

    Zahl n = null;
    Ganzzahl i = null;
    Objekt o = null;
    testGenericMethodDefine(n, i);/ /Zu diesem Zeitpunkt ist T eine Zahl, S ist eine Ganzzahl
    testGenericMethodDefine(o, i);//T ist ein Objekt, S ist eine Ganzzahl

    List list1 = null;
    testGenericMethodDefine3(i , list1)//Zu diesem Zeitpunkt ist T Number

    List list2 = null;
    testGenericMethodDefine4(list1, list2)//Kompilierungsfehler

    3.3 Wildcard
    in Die beiden oben genannten In diesem Abschnitt werden Typparametern bestimmte Werte zugewiesen. Darüber hinaus können Typparametern auch undefinierte Werte zugewiesen werden. Zum Beispiel:
    List unlimited Number> unlimitedNumberList;
    List von unbekanntem Typ Die Containerklasse kann nur die darin enthaltenen Elemente lesen, aber keine Elemente hinzufügen.
    Da ihr Typ unbekannt ist, kann der Compiler nicht erkennen, ob der Typ des hinzugefügten Elements mit dem Typ des Containers kompatibel ist. Die einzige Ausnahme ist NULL
    4. Array-Spezifikationstyp
    Sie können eine Klasse mit generischen Parameterwerten verwenden, um ein Array zu deklarieren, aber Sie können kein Array erstellen
    List[] iListArray;
    new ArrayList< Integer>[10];//Kompilierungszeitfehler

    5. Implementierungsprinzip

    5.1. Die generische Java-Kompilierungszeit-Technologie enthält keine generischen Informationen zur Laufzeit von Typparametern.
    Generika werden durch einen Front-End-Prozess namens Erasure durch den Java-Compiler implementiert. Man kann es sich (im Grunde) als eine Quelle-zu-Quelle-Transformation vorstellen, die die generische Version in die nicht-generische Version umwandelt.
    Grundsätzlich werden beim Löschen alle generischen Typinformationen entfernt. Alle Typinformationen zwischen spitzen Klammern werden verworfen, sodass beispielsweise ein
    List-Typ in List konvertiert wird. Alle Verweise auf Typvariablen werden durch die Obergrenze der Typvariablen (normalerweise Objekt) ersetzt. Außerdem
    wird immer dann, wenn der resultierende Codetyp falsch ist, eine Konvertierung in den entsprechenden Typ eingefügt.
                                                                                                                                                                                . Das bedeutet, dass sie keinen zusätzlichen Zeit- oder Platzaufwand verursachen, was sehr praktisch ist. Leider bedeutet dies auch
    , dass Sie sich bei der Typkonvertierung nicht auf sie verlassen können.

    5.2. Eine generische Klasse wird von allen ihren Aufrufen gemeinsam genutzt.
    Was wird durch den folgenden Code ausgegeben?
    List l1 = new ArrayList();
    List l2 = new ArrayList();
    System.out.println(l1.getClass() == l2.getClass());
    Vielleicht sagen Sie „falsch“, aber Sie liegen falsch. Es wird wahr ausgegeben. Weil alle Instanzen einer generischen Klasse zur Laufzeit dieselbe Laufzeitklasse haben, unabhängig von ihren tatsächlichen Typparametern.
    Tatsächlich wird ein Generikum als Generikum bezeichnet, weil es für alle möglichen Typparameter das gleiche Verhalten aufweist. Dieselbe Klasse kann für viele verschiedene
    Typen verwendet werden. Dadurch werden auch die statischen Variablen und Methoden der Klasse von allen Instanzen gemeinsam genutzt. Aus diesem Grund ist es illegal, Typparameter (Typparameter gehören zu bestimmten Instanzen) in statischen Methoden oder statischem Initialisierungscode
    oder beim Deklarieren und Initialisieren statischer Variablen zu verwenden.

    5.3. Casting und Instanz von
    Eine weitere Implikation, dass eine generische Klasse von allen ihren Instanzen gemeinsam genutzt wird, ist, dass es keinen Sinn macht zu prüfen, ob eine Instanz ein bestimmter Typ einer generischen Klasse ist.
    Collection cs = new ArrayList();
    if (cs caseof Collection) { ...} // Illegal
    Ähnlich ist die folgende Typkonvertierung
    Collection) cs;
    Erhalten Sie eine ungeprüfte Warnung, da die Laufzeitumgebung eine solche Prüfung nicht für Sie durchführt.

    6. Generische Verarbeitung der Klasse
    Nach Java 5 wird die Klasse generisch.
    Eine der Änderungen in JDK1.5 besteht darin, dass die Klasse java.lang.Class generisch ist. Dies ist ein interessantes Beispiel für die Erweiterung von Generika über Containerklassen hinaus.
    Nun hat die Klasse einen Typparameter T. Sie fragen sich vielleicht, wofür T steht? Es stellt den Typ dar, der durch das Class-Objekt dargestellt wird. Beispielsweise stellt der Typ
    String.class Class dar und Serializable.class stellt Class dar.
    Dies kann verwendet werden, um die Typsicherheit Ihres reflektierten Codes zu verbessern.
    Da insbesondere die newInstance()-Methode der Klasse jetzt ein T zurückgibt, können Sie beim Erstellen von Objekten mithilfe von Reflektion einen präziseren Typ erhalten.
    Angenommen, Sie möchten beispielsweise eine Toolmethode schreiben, um eine Datenbankabfrage anhand einer SQL-Anweisung durchzuführen und eine Sammlung von Objekten in der Datenbank zurückzugeben, die die Abfragebedingungen erfüllen
    .
    Eine Methode besteht darin, ein Factory-Objekt explizit zu übergeben, wie der folgende Code:
    interface Factory public T[] make();
    }
    public Collection select(Factory Factory, String-Anweisung) {
    Collection result = new ArrayList();
    /* SQL-Abfrage mit JDBC ausführen */
    für ( int i=0; i<10; i++ ) { /* über JDBC-Ergebnisse iterieren */
              T item = Factory.make();
                                                                              /
             result.add( item); {
                                                                                                                                                                                                ;EmpInfo> { ...
    public EmpInfo make() { return new EmpInfo(); }
    }
    Dann rufen Sie auf:
    select(getMyEmpInfoFactory(), "selection string" );
    Der Nachteil dieser Lösung besteht darin, dass sie eines von zwei Dingen erfordert:
    eine ausführliche anonyme Factory-Klasse an der Aufrufstelle oder die Deklaration einer Factory-Klasse für jeden zu verwendenden Typ und die Übergabe ihres Objekts an den Aufruf Seite
    Das ist unnatürlich.
    Die Verwendung von Klassentyp-Parameterwerten ist sehr natürlich und kann durch Reflexion verwendet werden. Code ohne Generika kann sein:
    Collection emps = sqlUtility.select(EmpInfo.class, ”select * from emps”); ...
    public static Collection select(Class c, String sqlStatement) {
    Collection result = new ArrayList()                                                                                                                                                                                                                                     Ergebnis .add(item); Der genaue Typ der Sammlung, den wir wollen. Da die Klasse nun generisch ist, können wir schreiben:
    Collection emps=sqlUtility.select(EmpInfo.class, ”select * from emps”); ;select(Classc, String sqlStatement) {
    Collection result = new ArrayList();
    /* SQL-Abfrage mit jdbc ausführen */
    für ( /* iterate über JDBC-Ergebnisse */ ) {
    T item = c.newInstance();
    /* Reflexion verwenden und alle Felder des Elements aus SQL-Ergebnissen festlegen */
    result.add(item);
    }
    return result;
    }
    um die gewünschte Sammlung typsicher zu erhalten.
    Diese Technik ist ein sehr nützlicher Trick, der in neuen APIs, die Anmerkungen verarbeiten, zu einer weit verbreiteten Redewendung geworden ist.

    7. Kompatibilität von altem und neuem Code

    7.1 Um die Codekompatibilität zu gewährleisten, wird die Typsicherheit durch Sie selbst gewährleistet
    Liste l = new ArrayList();
    List l = new ArrayList();

    7.2 Verwenden Sie kovariante Rückgabewerte mit Vorsicht.
    Ändern Sie beispielsweise den Code
    public class Foo {
    public Foo create(){
    } return new Foo();
    }
    }

    public Klasse Bar erweitert Foo {
    public Foo create(){
                                                                                                                                 use   using kovarianten Rückgabewertstil               use ’ s ’ s ‐ ‐ ‐ ‐ ‐‐ ‐ return new Bar(); pblic bar create () {
    Return New Bar ( );
    }
    }
    Seien Sie vorsichtig mit Ihrem Kunden Ihrer Bibliothek.




    Weitere Artikel zu Java-Generika finden Sie auf der chinesischen PHP-Website!


    Erklärung dieser Website
    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

    Heiße KI -Werkzeuge

    Undresser.AI Undress

    Undresser.AI Undress

    KI-gestützte App zum Erstellen realistischer Aktfotos

    AI Clothes Remover

    AI Clothes Remover

    Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

    Undress AI Tool

    Undress AI Tool

    Ausziehbilder kostenlos

    Clothoff.io

    Clothoff.io

    KI-Kleiderentferner

    AI Hentai Generator

    AI Hentai Generator

    Erstellen Sie kostenlos Ai Hentai.

    Heißer Artikel

    R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
    4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. Beste grafische Einstellungen
    4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
    4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. Chat -Befehle und wie man sie benutzt
    4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

    Heiße Werkzeuge

    Notepad++7.3.1

    Notepad++7.3.1

    Einfach zu bedienender und kostenloser Code-Editor

    SublimeText3 chinesische Version

    SublimeText3 chinesische Version

    Chinesische Version, sehr einfach zu bedienen

    Senden Sie Studio 13.0.1

    Senden Sie Studio 13.0.1

    Leistungsstarke integrierte PHP-Entwicklungsumgebung

    Dreamweaver CS6

    Dreamweaver CS6

    Visuelle Webentwicklungstools

    SublimeText3 Mac-Version

    SublimeText3 Mac-Version

    Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

    Lösen generische Funktionen das Problem der variadischen Parametertypen in Golang? Lösen generische Funktionen das Problem der variadischen Parametertypen in Golang? Apr 16, 2024 pm 06:12 PM

    Generische Funktionen in Go lösen das Problem variadischer Typen: Generische Funktionen ermöglichen die Angabe von Typparametern zur Laufzeit. Dadurch ist es möglich, Funktionen zu schreiben, die Parameter unterschiedlichen Typs verarbeiten können. Beispielsweise ist die Max-Funktion eine generische Funktion, die zwei vergleichbare Parameter akzeptiert und den größeren Wert zurückgibt. Durch die Verwendung generischer Funktionen können wir flexibleren und allgemeineren Code schreiben, der verschiedene Parametertypen verarbeiten kann.

    Spezifische Anwendungsszenarien von Generika in Golang Spezifische Anwendungsszenarien von Generika in Golang May 04, 2024 am 11:45 AM

    Anwendungsszenarien von Generika in Go: Erfassungsvorgänge: Erstellen Sie Erfassungsvorgänge, die für jeden Typ geeignet sind, z. B. zum Filtern. Datenstrukturen: Schreiben Sie allgemeine Datenstrukturen wie Warteschlangen, Stapel und Karten, um verschiedene Datentypen zu speichern und zu bearbeiten. Algorithmen: Schreiben Sie allgemeine Algorithmen wie Sortieren, Suchen und Reduzieren, die verschiedene Datentypen verarbeiten können.

    Was sind die Ober- und Untergrenzen von Java-Funktionsgenerika? wie benutzt man? Was sind die Ober- und Untergrenzen von Java-Funktionsgenerika? wie benutzt man? Apr 26, 2024 am 11:45 AM

    Generische Java-Funktionen ermöglichen das Festlegen von Ober- und Untergrenzen. Extends gibt an, dass der von einer Funktion akzeptierte oder zurückgegebene Datentyp ein Untertyp des angegebenen Typs sein muss, z. B. Die untere Grenze (super) gibt an, dass der von einer Funktion akzeptierte oder zurückgegebene Datentyp ein Supertyp des angegebenen Typs sein muss, z. B. Die Verwendung von Generika verbessert die Wiederverwendbarkeit und Sicherheit des Codes.

    Entdecken Sie die Vorteile und Einsatzmöglichkeiten von Generika in Golang Entdecken Sie die Vorteile und Einsatzmöglichkeiten von Generika in Golang Apr 03, 2024 pm 02:03 PM

    Antwort: Golang-Generika sind ein leistungsstarkes Tool zur Verbesserung der Wiederverwendbarkeit, Flexibilität, Typsicherheit und Skalierbarkeit von Code. Detaillierte Beschreibung: Vorteile: Wiederverwendbarkeit des Codes: Gemeinsame Algorithmen und Datenstrukturen Flexibilität: Laufzeiterstellung von Instanzen bestimmter Typen Typsicherheit: Typprüfung zur Kompilierungszeit Erweiterbarkeit: Einfache Erweiterung und Anpassung Zweck: Gemeinsame Funktionen: Sortieren, Vergleich Gemeinsame Datenstrukturen wie Listen , Karten, Stapel usw. Typaliase: Typdeklarationen vereinfachen. Eingeschränkte Generika: Typsicherheit gewährleisten

    Anwendung von Java-Generika in der Android-Entwicklung Anwendung von Java-Generika in der Android-Entwicklung Apr 12, 2024 pm 01:54 PM

    Die Anwendung von Generika in der Android-Entwicklung verbessert die Wiederverwendbarkeit, Sicherheit und Flexibilität des Codes. Die Syntax besteht aus der Deklaration einer Typvariablen T, die zum Bearbeiten typparametrisierter Daten verwendet werden kann. Zu den in Aktion befindlichen Generika gehören benutzerdefinierte Datenadapter, die es dem Adapter ermöglichen, sich an jede Art von benutzerdefinierten Datenobjekten anzupassen. Android bietet außerdem generische Listenklassen (z. B. ArrayList) und generische Methoden, die die Manipulation von Parametern unterschiedlicher Typen ermöglichen. Zu den Vorteilen der Verwendung von Generika gehören die Wiederverwendbarkeit, Sicherheit und Flexibilität des Codes. Es muss jedoch darauf geachtet werden, die richtigen Grenzen anzugeben und diese in Maßen zu verwenden, um die Lesbarkeit des Codes sicherzustellen.

    Welche Einschränkungen gibt es bei generischen Funktionen in Golang? Welche Einschränkungen gibt es bei generischen Funktionen in Golang? Apr 16, 2024 pm 05:12 PM

    Einschränkungen der generischen Go-Funktionen: Es werden nur Typparameter unterstützt, Wertparameter werden nicht unterstützt. Funktionsrekursion wird nicht unterstützt. Typparameter können nicht explizit angegeben werden, sie werden vom Compiler abgeleitet.

    Welchen Einfluss haben Golang-Generika auf Funktionssignaturen und Parameter? Welchen Einfluss haben Golang-Generika auf Funktionssignaturen und Parameter? Apr 17, 2024 am 08:39 AM

    Zu den Auswirkungen von Generika auf Go-Funktionssignaturen und -Parameter gehören: Typparameter: Funktionssignaturen können Typparameter enthalten, die die Typen angeben, die die Funktion verwenden kann. Typeinschränkungen: Typparameter können Einschränkungen haben, die Bedingungen angeben, die sie erfüllen müssen. Parametertyp-Inferenz: Der Compiler kann auf den Typ nicht spezifizierter Typparameter schließen. Angeben von Typen: Parametertypen können explizit angegeben werden, um generische Funktionen aufzurufen. Dies erhöht die Wiederverwendbarkeit und Flexibilität des Codes und ermöglicht Ihnen das Schreiben von Funktionen und Typen, die mit mehreren Typen verwendet werden können.

    Wie funktionieren Java-Enum-Typen mit Generika? Wie funktionieren Java-Enum-Typen mit Generika? May 04, 2024 am 08:36 AM

    Die Kombination von Aufzählungstypen und Generika in Java: Wenn Sie eine Aufzählung mit Generika deklarieren, müssen Sie spitze Klammern hinzufügen, und T ist der Typparameter. Wenn Sie eine generische Klasse erstellen, müssen Sie auch spitze Klammern hinzufügen. T ist ein Typparameter, der jeden Typ speichern kann. Diese Kombination verbessert die Codeflexibilität, die Typsicherheit und vereinfacht den Code.

    See all articles