Fragen zu Java-Interviews (Reihe) – Unveränderliche Klasse

Verändere sie nicht, sie will nicht verändert werden! 🧩

Knapp

An einem bestimmten Punkt wird sich das Gespräch in den meisten Java-Interviews natürlich in Richtung des bewegen immutable Wort.

Entweder ist es nach dem Reden String und warum ist es unveränderlich oder beim diskutieren HashMap-Interna.

Am Ende dieses Beitrags werden Sie sich viel wohler fühlen, wenn Sie die folgenden Fragen beantworten und das Thema erweitern.

🔸 Was ist eine unveränderliche Klasse?

🔸 Wie würdest du einen erstellen?

🔸 Wofür ist es nützlich?

🔸 Kennst du Beispiele für unveränderliche Java-Klassen?

Weitere Beiträge wie diesen finden Sie auf new-spike.net 🚀

Implementierung

🔵 Ein immutable class ist eine Klasse, deren Interna sich über den Lebenszyklus der Anwendungen nicht ändern.

Anstatt nur die Eigenschaften davon aufzuzählen, machen wir es etwas anders.

🚀 Wir gehen von einer einfachen Klasse zu einer unveränderlichen Klasse.

public class Dog {
    public String name;
}

Hund.java

1️⃣ Alle Felder in Ihrer Klasse sollten nur über den Konstruktor initialisiert werden.

public class Dog {
    public String name;
        
    public Dog(String name) {
        this.name = name;
    }
}

Hund.java

2️⃣ Die inneren Felder sollten auch als deklariert werden final und private ohne Setter-Methoden für sie.

Auf diese Weise können sie nach der Initialisierung nicht mehr geändert werden und sollten nur über Getter-Methoden zugänglich sein.

public class Dog {
    private final String name;
        
    public Dog(String name) {
        this.name = name;
    }
    
    public String getName() {
        return this.name;
    }
}

Hund.java

3️⃣ Die Klasse sollte deklariert werden als final Es kann also nicht um andere Klassen erweitert werden und erhält die Möglichkeit, auf die Felder zuzugreifen.

public final class Dog {
    private final String name;
        
    public Dog(String name) {
        this.name = name;
    }
    
    public String getName() {
        return this.name;
    }
}

Hund.java

Weitere Beiträge wie diesen finden Sie auf new-spike.net 🚀

💯 An dieser Stelle haben wir eine immutable Klasse.

❓ Was ist nun, wenn wir ein neues Feld eines benutzerdefinierten Typs hinzufügen möchten?

🔵 Sagen wir, wir wollen den Geburtsort des Hundes wissen. Lassen Sie uns eine einfache Adressklasse erstellen.

public class Address {
    public String streetName;
    public String streetNo;

    public Address(String streetName, String streetNo) {
        this.streetName = streetName;
        this.streetNo = streetNo;
    }
}

Adresse.java

Wir fügen es als Feld innerhalb der hinzu Dog Klasse.

Um unsere Klasse zu halten immutablemüssen wir das Feld als deklarieren private und final und haben eine Getter-Methode, um die Adressdetails abzurufen.

public final class Dog {
    private final String name;
    private final Address birthPlace;
        
    public Dog(String name, Address birthPlace) {
        this.name = name;
        this.birthPlace = birthPlace;
    }
    
    public String getName() {
        return this.name;
    }
    
    public Address getBirthPlace() {
        return this.birthPlace;
    }
}

Hund.java

❗️ Wir könnten denken, das wars. Wir würden uns irren!

Aber wie konnte das sein? Wir haben alles genauso gemacht wie für die name aufstellen.

Um zu verstehen, warum, werfen wir einen Blick auf ein Beispiel, in dem wir die verwenden Dog Klasse.

public class ImmutableClassApplication {

    public static void main(String[] args) {

        Dog dog = new Dog("Max", new Address("Oxford", "23A"));

        dog.getBirthPlace().streetName = "Bingham"; // change the street of the dog's birth place.

        System.out.println("Dog name: " + dog.getName() 
        + "\n Street: " + dog.getBirthPlace().getStreetName()
        + "\n Number: " + dog.getBirthPlace().getStreetNo());
    }

}

Ausgabe :

Dog name: Max
Street: Bingham
Number: 23A

Weitere Beiträge wie diesen finden Sie auf new-spike.net 🚀

❗️ Wie Sie sehen können, können wir den Wert von tatsächlich aktualisieren birthPlace Feld und ändern implizit die dog Objekt.

Aus diesem Grund werden nicht nur innere Felder als deklariert private und final und nicht definierende Setter, sollten Sie auch einen Blick auf Ihre inneren Felder werfen immutable.

❗️ Der Unterschied zwischen den beiden Feldern ist der String wird implizit deklariert immutable auf Java.

Schau mal vorbei dieser Beitrag um viel mehr darüber zu erfahren, was mit einem String hinter den Kulissen passiert!

🧩 Neben String sind weitere vordefinierte Klassen in Java unveränderlich, wie z Integer und Long usw.

🔵 Allerdings besteht die Lösung darin, die zu ändern Address Klasse, es zu schaffen immutable.

public final class Address {
    private final String streetName;
    private final String streetNo;

    public Address(String streetName, String streetNo) {
        this.streetName = streetName;
        this.streetNo = streetNo;
    }

    public String getStreetName() {
        return streetName;
    }

    public String getStreetNo() {
        return streetNo;
    }
}

Adresse.java

❗️ Diese Lösung ist realisierbar, wenn wir den benutzerdefinierten Typ tatsächlich ändern können, um ihn unveränderlich zu machen.

Aber was, wenn wir das nicht machen wollen Address Klasse unveränderlich, wegen anderer Abhängigkeiten von ihr. Was können wir jetzt machen?

🔵 Die Lösung in diesem Fall besteht darin, einen Klon des Objekts in der jeweiligen Getter-Methode abzurufen.

1️⃣ Dazu müssen wir dem einen neuen Konstruktor hinzufügen Address Klasse, Empfang einer Address Objekt als Parameter.

public final class Address {
    private final String streetName;
    private final String streetNo;

    public Address(String streetName, String streetNo) {
        this.streetName = streetName;
        this.streetNo = streetNo;
    }
    
    // clone constructor
    public Address(Address address) {
        this.streetName = address.getStreetName();
        this.streetNo = address.getStreetNo();
    }

    public String getStreetName() {
        return streetName;
    }

    public String getStreetNo() {
        return streetNo;
    }
}

2️⃣ Jetzt, wo wir den Hund holen müssen birthPlace Wir werden einen Klon dieses Objekts abrufen.

public final class Dog {
    private final String name;
    private final Address birthPlace;
        
    public Dog(String name, Address birthPlace) {
        this.name = name;
        this.birthPlace = birthPlace;
    }
    
    public String getName() {
        return this.name;
    }
    
    public Address getBirthPlace() {
        return new Address(this.birthPlace);
    }
}

3️⃣ Nach dieser Änderung hat das Ausführen des vorherigen Codes eine andere Ausgabe.

public class ImmutableClassApplication {

    public static void main(String[] args) {

        Dog dog = new Dog("Max", new Address("Oxford", "23A"));

        dog.getBirthPlace().streetName = "Bingham"; // the change will be done on the clone and not the actual value of the dog's birth place

        System.out.println("Dog name: " + dog.getName() 
        + "\n Street: " + dog.getBirthPlace().getStreetName()
        + "\n Number: " + dog.getBirthPlace().getStreetNo());
    }

}

ImmutableClassApplication.java

Ausgabe :

Dog name: Max
Street: Oxford
Number: 23A

❓ Jetzt, da wir wissen, wie man eine erstellt immutable und worauf ist zu achten, was ist der eigentliche Zweck?

🧩 Die häufigsten Verwendungen sind:

1️⃣ Lassen Sie eine benutzerdefinierte Klasse als Schlüssel in einer Karte verwenden.

🔹 Der Grund dafür ist, dass der Hash eines unveränderlichen Objekts immer gleich sein wird und in Bezug auf die Leistung viel besser funktionieren würde.

2️⃣ Halten Sie Werte in einer Multithread-Anwendung.

🔹 Weil Sie sich keine Gedanken darüber machen müssen, dass verschiedene Threads den internen Zustand des Objekts ändern.

Weitere Beiträge wie diesen finden Sie auf new-spike.net 🚀

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *