[JAVA] Wie man denkt, wenn man plötzlich etwas über Generika versteht

Überblick

Die Generika sind "Argumente". Ich werde die Gedanken zusammenfassen, die ich dachte "Ah, ich verstehe", als ich mit Generika nicht ganz richtig lag.

Referenzierte Site

Vielen Dank für die Weisheit unserer Vorgänger. http://d.hatena.ne.jp/Nagise/20101105/1288938415

Java-Umgebung

java version 1.8.0_181 Java(TM) SE Runtime Environment (build 1.8.0_181-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

src └example   └java     └generics       ├ Main.java       └ GenericsSample.java

Das Wertargument ist die Methode, nicht wahr?

Klammern () ← Dies ist

Die Methode ist diese Klammer (). Diese Klammer () ist das gleiche Symbol an der Stelle der Methodendeklaration und der Stelle des Methodenaufrufs, wird jedoch in einer anderen Bedeutung verwendet. Es handelt sich um Informationen, die den "in der Methode verwendeten Wert" angeben.

Main.java


package example.java.generics;

public class Main {
    public static void main(String[] args) {
        int result = plus(2, 5); //Hier  "()Deklariert "Die Methode wird mit dem Wert dieses Arguments ausgeführt"(Tatsächliches Argument)
        System.out.println(result);
    }

    public static int plus(int T, int S) { //Hier "()Erklärt "Ich werde ein Argument mit diesem Argumentnamen erhalten"(Formelles Argument)
        return T + S;
    } // T,Reichweite von S bis hierher
}

Natürlich können Sie es richtig machen function_2.JPG

Apropos Typargumente, es sind Generika, nicht wahr?

Yamakasa <> ← Dies ist

Apropos Yamakasa <> ...? Ja, es sind Generika. Diese spitze Klammer <> ist das gleiche Symbol anstelle der Generika-Deklaration und der Stelle des Generika-Aufrufs (ich wage es zu sagen), wird jedoch in einer anderen Bedeutung verwendet. Es handelt sich um Informationen zum Anzeigen von "in Klassen und Methoden verwendeten Typen".

GenericsSsample.java


package example.java.generics;

public class GenericsSample {
    //Hier "<>Erklärt "Ich werde den Typ mit diesem Argumentnamen erhalten"(Formelles Argument)
    public <T> void callGenerics(T value){
        System.out.println(value); //Was ist der Wert des Arguments?
        System.out.println(value.getClass().getName()); //Was ist der Argumenttyp?
    } //Bereich von T bis hier
}

Main.java


package example.java.generics;

public class Main {
    public static void main(String[] args) {
        GenericsSample genericsSample = new GenericsSample();
        
        //Hier "<>Erklärt "Ich werde die Methode mit einem Wert dieses Typs ausführen"(Tatsächliches Argument)
        //Hier  "()Deklariert "Die Methode wird mit dem Wert dieses Arguments ausgeführt"(Tatsächliches Argument)
        //Geben Sie einfach mit jedem Symbol verschiedene Arten von tatsächlichen Argumenten an
        genericsSample.<Integer>callGenerics(1234);
    }
}

Dies ist der Wert und der Typ, die vom Argument richtig festgelegt wurden generics_3.JPG generics_8.JPG

Wenn der Typwert und der Typ des als Argument übergebenen Werts (schwer zu verstehen, ...) unterschiedlich sind

Main.java


package example.java.generics;

public class Main {
    public static void main(String[] args) {
        GenericsSample genericsSample = new GenericsSample();
        genericsSample.<String>callGenerics(1234);
    }
}

Luft stören generics_6.JPG

Wird sicher versagen generics_7.JPG

Schreiben Sie in der Reihenfolge Typ → Wert

In Java an erster Stelle

//Reihenfolge der Typvariablen
String variable;

Da es wie in "Typ-> Reihenfolge" geschrieben ist, ist es verständlich, dass die Reihenfolge der Argumente, die den Typ und den Wert darstellen, auch "generisch-> Wert" ist.

//Typ → Wert
//Der Grund, warum das Generikum, das den Typ darstellt, vor dem Leerzeichen steht, ist, dass der Rückgabetyp das im Generikum angegebene Argument sein kann.(In diesem Fall "T")Weil es gibt(vielleicht)
public <T> void callGenerics(T value)

//Typ → Wert
genericsSample.<String>callGenerics(1234);

Für die Klasse angegebene Generika

Wie die Methode hat die Klasse nur eine Deklaration (formales Argument), die besagt "Ich werde den Typ mit diesem Argumentnamen akzeptieren".

GenericsSample.java


package example.java.generics;

//Hier "<>Erklärt "Ich werde den Typ mit diesem Argumentnamen erhalten"(Formelles Argument)
public class GenericsSample<T> {

    //Der Gültigkeitsbereich des Arguments T des in der Klasse angegebenen Typs setzt sich mit der Methode in der Klasse fort
    public void callGenerics(T value){
        System.out.println(value); //Was ist der Wert des Arguments?
        System.out.println(value.getClass().getName()); //Was ist der Argumenttyp?
    }
} // <T>Bereich bis hierher

Main.java


package example.java.generics;

public class Main {
    public static void main(String[] args) {
        //Hier "<>Erklärt "Ich werde eine Klasse mit einem Wert dieses Typs instanziieren"(Tatsächliches Argument)
        // new GenericsSample<Integer>Ist neues GenericsSample<>Es ist in Ordnung, es wegzulassen(GenericsSample<Integer>Warum ist es Integer? Schlussfolgerungen)
        GenericsSample<Integer> genericsSample = new GenericsSample<Integer>();

        //Hier  "()Deklariert "Die Methode wird mit dem Wert dieses Arguments ausgeführt"(Tatsächliches Argument)
        genericsSample.callGenerics(1234);
    }
}

generics_15.JPG generics_9.JPG

Natürlich, wenn Sie einen anderen Typ für die Methode angeben. .. ..

Main.java


package example.java.generics;

public class Main {
    public static void main(String[] args) {
        //Hier "<>Erklärt "Ich werde eine Klasse mit einem Wert dieses Typs instanziieren"(Tatsächliches Argument)
        // new GenericsSample<Integer>Ist neues GenericsSample<>Es ist in Ordnung, es wegzulassen(GenericsSample<Integer>Warum ist es Integer? Schlussfolgerungen)
        GenericsSample<Integer> genericsSample = new GenericsSample<Integer>();

        //Hier  "()Deklariert "Die Methode wird mit dem Wert dieses Arguments ausgeführt"(Tatsächliches Argument)
        genericsSample.callGenerics("test");
    }
}

Luft stören generics_10.JPG

Wird sicher versagen generics_11.JPG

Wenn <> sowohl an die Klasse als auch an die Methode mit demselben Argumentnamen angehängt ist. ..

GenericsSample.java


package example.java.generics;

//Hier "<>Erklärt "Ich werde den Typ mit diesem Argumentnamen erhalten"(Formelles Argument)
public class GenericsSample<T> {

    //Hier "<>Erklärt "Ich werde den Typ mit diesem Argumentnamen erhalten"(Formelles Argument)
    //Der Gültigkeitsbereich des Arguments T des in der Klasse angegebenen Typs setzt sich mit der Methode in der Klasse fort... ??
    public <T> void callGenerics(T value){
        System.out.println(value); //Was ist der Wert des Arguments?
        System.out.println(value.getClass().getName()); //Was ist der Argumenttyp?
    }
} // <T>Bereich bis hierher... ??

Main.java


package example.java.generics;

public class Main {
    public static void main(String[] args) {
        //Hier "<>Erklärt "Ich werde eine Klasse mit einem Wert dieses Typs instanziieren"(Tatsächliches Argument)
        // new GenericsSample<Integer>Ist neues GenericsSample<>Es ist in Ordnung, es wegzulassen(GenericsSample<Integer>Warum ist es Integer? Schlussfolgerungen)
        GenericsSample<Integer> genericsSample = new GenericsSample<Integer>();

        //Hier  "()Deklariert "Die Methode wird mit dem Wert dieses Arguments ausgeführt"(Tatsächliches Argument)
        genericsSample.callGenerics("test");
    }
}

Überhaupt nicht störend generics_12.JPG generics_13.JPG

Ich werde nicht scheitern ... generics_14.JPG

Die Ursache hierfür ist **, wobei "<>" deklariert "Ich werde den Typ mit diesem Argumentnamen erhalten" (formales Argument) **

Weil ich es mit dem gleichen Argumentnamen angegeben habe. Ich habe es mit einer neuen lokalen Typvariablen in der Methode überschrieben. Es fühlt sich an wie ↓.

GenericsSample.java


package example.java.generics;

//Hier "<>Erklärt "Ich werde den Typ mit diesem Argumentnamen erhalten"(Formelles Argument)
public class GenericsSample<T> {

    //Innerhalb der Klasse das tatsächliche Argument der zum Zeitpunkt der Instanz der Klasse angegebenen Generika(new GenericsSample<Integer>Ganze Zahl)Ist gültig

    //Der Umfang des Arguments T des in der Klasse angegebenen Typs ist das tatsächliche Argument der zum Zeitpunkt der Methode angegebenen Generika(Diesmal String)Wurde überschrieben mit
    // genericsSample.callGenerics("test");von"test"Von ""test"Weil es ein String ist<T>vonTはStringだ!」と推論された)
    public <T> void callGenerics(T value){
        System.out.println(value); //Was ist der Wert des Arguments?
        System.out.println(value.getClass().getName()); //Was ist der Argumenttyp?
    }
}

Kann es beim Deklarieren einer statischen Klasse nicht angegeben werden?

**kann nicht. ** ** ** Für nicht statische Klassen

//Hier "<>Erklärt "Ich werde eine Klasse mit einem Wert dieses Typs instanziieren"(Tatsächliches Argument)
// new GenericsSample<Integer>Ist neues GenericsSample<>Es ist in Ordnung, es wegzulassen(GenericsSample<Integer>Warum ist es Integer? Schlussfolgerungen)

Aber wenn es sich um eine statische Klasse handelt, können Sie die Klasse nicht instanziieren, oder? Es ist unmöglich, weil es kein Timing gibt, um das tatsächliche Argument anzugeben und es zu erstellen. .. (Wenn es sich jedoch um eine statische Methodeneinheit handelt, können Sie das tatsächliche Argument zum Zeitpunkt des Aufrufs angeben, sodass Sie das Typargument der Generika angeben können!)

Fazit

Keine Panik, denn es ist nur ein Streit.

Recommended Posts

Wie man denkt, wenn man plötzlich etwas über Generika versteht
So ersetzen Sie Zeichen, die Sie nicht verstehen [Prinzip]
Überlegen Sie, wie Sie MVC in M und V unterteilen können
Dinge, über die Sie nachdenken sollten, wenn Sie sich für die Architektur eines neuen Systems entscheiden
Wie man über Klassengestaltung (Division) in einem Geschäftssystem nachdenkt (1)
Verstehe in 5 Minuten !! Wie man Docker benutzt
Über "Dependency Injection" und "Inheritance", die leicht zu verstehen sind, wenn man sich zusammen erinnert
[Rails] Wie schreibe ich, wenn ich eine Unterabfrage mache?
Verstehen, wie Spring DB-Verbindungen (DB-Transaktionen) freigegeben werden
Wenn Sie InputStream in JDBI3 binden möchten
Wenn Sie die Methode außerhalb verwenden möchten
So löschen Sie die Datenbank beim Neuerstellen der App
Was verwenden Sie beim Konvertieren in String?
[Ruby] Wenn Sie mehrere Zeichen ersetzen möchten
So löschen Sie den dem Benutzer zugeordneten Tweet, wenn Sie ihn gleichzeitig löschen
Wie erstelle ich ein Vagrant Plugin, das Sie gelernt haben, als Sie Vagrant-Mutagen gegabelt und veröffentlicht haben?
Verstehst du wirklich So überprüfen Sie die von der App verwendete Bibliothek und Lizenz
Der Standpunkt bei der Codeüberprüfung einer Webanwendung (Rails)
Zusammenfassung der Punkte, über die ich mir bei der Migration von Java nach Kotlin Sorgen gemacht habe
Zu überprüfende Punkte, wenn Rubocop nur langsam ausgeführt wird
Informationen zur Ausnahmebehandlung
Informationen zur Ausnahmebehandlung
Wie man denkt, wenn man plötzlich etwas über Generika versteht