Erfahren Sie, wie Java die Typintegrität schützt

Was

――Durch die jahrelange Arbeit mit PHP hat sich mein Wissen über Java verringert, daher werde ich mich daran erinnern und es zusammenfassen (hauptsächlich über komplizierte Teile von Typen).

Was war unveränderlich und veränderte sich?

Was war die Marke T, Extends usw., die in der Deklaration der Klasse oder Methode enthalten war?

class Animal {
    public int getAge() {
        return 3;
    }
}

class Dog extends Animal {
    @Override
    public int getAge() {
        return 33;
    }
    //Methoden nur in der Hundeklasse
    public String getName() {
        return "john";
    }
}

class AnimalBox<T extends Animal> {
    T someAnimal;
    
    public AnimalBox(T animal) {
        someAnimal = animal;
    }
    
    public int getAge() {
        return someAnimal.getAge();
    }
}

―― ~~ In diesem Fall können Sie jedoch, wenn Sie es einfach als Tiertyp festlegen, Hund einfügen und dasselbe tun, sodass ich nicht weiß, wie ich es richtig verwenden soll (dies ist ein Problem) ~ ~ ――Für das obige Problem kann der generische Typ von Dog zurückgegeben werden, wenn Sie public T get () implementieren, aber AnimalBox2 kann nur Animal zurückgeben. In dem Kommentar habe ich ein Beispiel für den Unterschied erläutert.

//Das ist in Ordnung
class AnimalBox2 {
    Animal someAnimal;
    
    public AnimalBox2(Animal animal) {
        someAnimal = animal;
    }
    
    public int getAge() {
        return someAnimal.getAge();
    }
}
class Box<T> {
    T someValue;
    List<T> history = new ArrayList<>();
    
    public Box(T v) {
        someValue = v;
    }
    
    public T get() {
        return someValue;
    }
    
    public void selectOne(Box<? extends T> box) {
        history.add(box.get());
    }
}

Was bedeutet es, den generischen Typ zu vergessen und ihn einer Unterklasse zuzuordnen?

    Dog d = new Dog();
    Animal a = d; //Obwohl es sich um einen anderen Typ handelt, kann er zugewiesen werden, da es sich um eine Unterklasse handelt
        
    System.out.println(a.getClass().getName()); //Dog
    System.out.println(a.getAge()); //33
    System.out.println(d.getName()); //john
    System.out.println(a.getName()); //error: cannot find symbol

--Von oben)

SpaceDog sd = new Dog(); //Dog cannot be converted to SpaceDog

Was bedeutet generische Unveränderlichkeit?

――Was ist, wenn der generische Typ kovariant ist?

        List<SpaceDog> spaceDogList = new ArrayList<>();
        List<Dog> dogList = spaceDogList; //(Wenn es eine Veränderung war)Obwohl es sich um einen anderen Typ handelt, kann er zugewiesen werden, da es sich um eine Unterklasse handelt
        dogList.add(new Dog());

--Dog hat List \ über die Variable dogList eingegeben. Dies ist ein Problem bei der Verwendung von spaceDogList. Es ist unveränderlich, dies zu verhindern.

Warum sind die Sequenzen kovariant?

»Es ist nicht geworden. Es führt nicht zu einem Kompilierungsfehler, aber zu einem Laufzeitfehler.

        SpaceDog[] spaceDogArray = new SpaceDog[1];
        Dog[] dogArray = spaceDogArray;
        dogArray[0] = new Dog(); //Laufzeit Fehler:java.lang.ArrayStoreException: Dog

Ist es nicht dasselbe für gewöhnliche Klassen, die keine generischen Typen sind, dass die Variable einen Verweis auf die Entität hat und ihre Interpretation in der Klassenvererbung je nach Situation unterschiedlich ist?

――Sie verstehen möglicherweise nicht, was Sie sagen ―― ↓ Kann in einem solchen Fall die Variable a verwendet werden, um die Typzusammensetzung zu zerstören?

        Dog d = new Dog();
        Animal a = d;
        //Ich möchte die Variable a irgendwie verwenden, damit die Variable d zur Vereinfachung der Typinterpretation in Schwierigkeiten gerät.

――Ich kann nur an das Erstellen und Überschreiben denken, aber d ist kein Problem, da es nicht überschrieben und an einem anderen Ort erstellt wird.

        Dog d = new Dog();
        Animal a = d;
        System.out.println(d); //Dog@77468bd9 
        System.out.println(a); //Dog@77468bd9
        a = new Animal();
        System.out.println(a); //Animal@12bb4df8

Organisieren der Beziehung zwischen generischen Typen und Typparametern

        List<Dog> dogList = new ArrayList<>();
        dogList.add(new Dog());
        dogList.add(new SpaceDog());

――Ich kann das nicht

class Box<T> {
    T someValue;
    List<T> history = new ArrayList<>();
    
    public Box(T v) {
        someValue = v;
    }

    public void set(T v) {
        someValue = v;
    }
    
    public T get() {
        return someValue;
    }
    
    public void selectOne(Box<T> box) {
        history.add(box.get());
    }
}

Box<Dog> dogBox = new Box<>(new Dog());
Box<SpaceDog> spaceDogBox = new Box<>(new SpaceDog());
dogBox.selectOne(spaceDogBox); //Kompilierungsfehler:Box<Dog>Und Box<SpaceDog>Ist ein anderer Typ

――Sie können es so machen

    public void selectOne(Box<? extends T> box) {
        history.add(box.get());
    }

――Warum ist der Typ konsistent?


    public void selectOne(Box<? extends T> box) {
        history.add(box.get());
        box.set(someValue); //Kompilierungsfehler
    }

Was ist \ <? Super T>?

--Wenn Sie der Meinung sind, dass das obige \ <? Extends T> "die Invarianz des generischen Typs abschwächt (kovariiert), indem die Funktion der Variablen zum Abrufen des Werts eingeschränkt wird",

Zusammenfassung

――Wenn eine normale Klasse die Attribute und Verhaltensweisen bestimmter Objekte (Tiere, Hunde usw.) zusammenfasst, wird der generische Typ so dargestellt, dass die Zusammenfassung *** in einen anderen Kontext eingeschlossen wird. Machen

Musterdiagramm

java.png

Recommended Posts

Erfahren Sie, wie Java die Typintegrität schützt
So finden Sie Java-Primzahlen
Verwendung des Java-Aufzählungstyps
So finden Sie heraus, welche Java-Version der Klassendatei kompiliert wurde
Java-Typkonvertierung
[Java] Aufzählungstyp
Java Optionaler Typ
Java-Doppeltyp
java: Wie schreibe ich eine generische Typliste? [Hinweis]
[Java] So schneiden Sie eine Zeichenfolge zeichenweise aus
Ich habe versucht herauszufinden, was sich in Java 9 geändert hat
[Java] Datentyp ①-Basistyp
Informieren Sie sich über Docker
[Java, Kotlin] Typabweichung
Feld für den Java-Klassentyp
Typbestimmung in Java
Java # 1 studieren (typischer Typ)
Wie man einen Schrägstrich zurückschlägt \
[Java] Konvertierung des Datumstyps
Suchen Sie die Adressklasse und den Adresstyp aus der IP-Adresse mit Java
Unterschied zwischen Java und JavaScript (wie man den Durchschnitt findet)
Finden Sie alle Zeitzonen-IDs heraus, die von der Java TimeZone-Klasse unterstützt werden