Strings unveränderlich????

TMT

Neues Mitglied
Ich habe gerade folgende Aussage gelesen.

Die Zeichenkette-Klasse in Java ist unveränderlich, was bedeutet, dass der Inhalt einer Zeichenkette nach der Erstellung nicht mehr geändert werden kann.
Das kann ich nicht so ganz glauben, denn:
Java:
String strValue = "Hallo";
        strValue = "Welt";

Oder was sagen andere dazu?
 

RennesVin

Mitglied
Du hast da eine Neuzuweisung an strValue. Der vorher mit der Variable strValue gespeicherte Wert (das String-Obj) ändert sich nicht und wird weggeworfen. Einen String kannst du nicht ändern, auch ein StringBuilder kann das nicht, weil die Klasse final ist und alle Attribute ebenso. Merke: Das String-Manging (hier umgang mit Variablen) ist etwas anderes als eine String-Manipulation.
 

RennesVin

Mitglied
Daraus lässt sich allerdings nicht schließen, dass der Inhalt einer Instanz dieser Klasse unveränderlich ist
doch, weil
Du kannst halt keine weiteren Klassen davon ableiten
die möglicherweise Attribute verändern könnten.

Oder einfacher gesagt, es gehört zum Immutable-Pattern dazu, dass auch die Klasse final ist.

Aber ich bin mir sicher, dass das bereits bewusst war und nur die richtige Formulierungsweise fehlte.
 

KonradN

Super-Moderator
Mitarbeiter
Das ist aber "nur" ein best Practice, wie es z.B. in Effective Java beschrieben wurde. Nur weil es eine abgeleitete Klasse geben kann, die nicht unveränderlich ist, ändert das ja nichts daran, dass die Klasse selbst unveränderlich ist. Wenn jemand Quatsch macht, dann macht diese Person eben Quatsch. Das hast Du aber generell - jeder Verstoss gegen Liskovs Substitution Principle ist nichts anderes: Der Contract der Basis Klasse wird verletzt.

Daher sind das durchaus zwei unterschiedliche Dinge, die man nicht durcheinander mischen sollte. Denn unter dem Strich besagt es nur, dass man Elemente, die man immutable haben will, final machen sollte. Da es in der Regel einfache Klassen sind, die eigene Werte beinhalten, ist das relativ einfach. Aber es ist zumindest denkbar, dass man eben doch eine Hirarchie braucht. Dann erbt B von A und beide sollen immutable sein. Dann kann aber A nicht final sein.
 

KonradN

Super-Moderator
Mitarbeiter
Das hat nichts mit Quatsch machen zu tun, sondern mit richtiger Programmierung
Ich denke, Du hast meine Aussage schlicht missverstanden. Von einer Klasse, die immutable ist und nicht final, zu erben und ihr dann einen veränderlichen State zu geben, verstößt gegen Liskovs Substitution Principle und ist damit in meinen Augen Quatsch und auf keinen Fall "richtige Programmierung".

Aber das muss man nicht diskutieren. Kernpunkt ist und war:
Immutable class bedeutet nicht zwingend, dass de class final ist. Sie sollte es sein, aber das ist keine zwingende Voraussetzung.
Und den Punkt haben wir dann ja jetzt wohl abgehakt, oder?
 

temi

Top Contributor
es gehört zum Immutable-Pattern dazu, dass auch die Klasse final ist.
Das Eine bedingt allerdings nicht das Andere. Deshalb ist deine Schlussfolgerung ganz einfach falsch.

Das kann ich dir auch beweisen:
Java:
public final class Mutabel {
   
    private int value;
   
    public void mutate(int value) {
        this.value = value;
    }
   
    public int getValue() {
        return value;
    }
}

Klasse final, Inhalt nicht. QED.

Ich bin sicher, dass weißt du auch. Immerhin ist der Inhalt des StringBuilders veränderbar. Erst die Instanz von String, die du z. B. mit toString() erhältst ist es nicht mehr.

Aber ich bin mir sicher, dass das bereits bewusst war und nur die richtige Formulierungsweise fehlte.
Meine Formulierung war genau so gemeint, wie sie geschrieben wurde.
Kernpunkt ist und war:
Immutable class bedeutet nicht zwingend, dass de class final ist.
Kernpunkt ist: Eine Klasse die final ist, muss nicht zwingend unveränderbar sein. :) Und im Fall des oben genannten StringBuilders ist es schlicht auch falsch, weil er veränderbar ist.
 
Zuletzt bearbeitet:

temi

Top Contributor

Blender3D

Top Contributor
Tatsächlich zwingend?
Ja sonst kann ich folgendes machen und die geerbte Klasse ist nicht mehr immutable;
Java:
class Immutable2 extends Immutable {
    public int wichtigerWert ;
 
    public Immutable2(int value) {
        super(value);
    }
 
    public void mutate(int value) {
        this.value = value; // Fehler!!!
    }

}
Aber versuche einmal die Klasse String zu erweitern.
Unveränderbar ist absolut. Deshalb darf es von einer unveränderbaren Klasse auch keine neue ( veränderte) Klasse geben.
 

KonradN

Super-Moderator
Mitarbeiter
Also das wird jetzt massive Wortklauberei.

Erst einmal müssen wir die Begriffe definieren. Schon, dass man von "immutable class" gesprochen hat, ist Quatsch. Immutable sind Objekte. Da kann man z.B. als Definition nehmen:
An immutable object is an object whose internal state remains constant after it has been entirely created
Immutable Objects in Java | Baeldung

Und wenn man den Baeldung Beitrag anschaut, dann sieht man auch ein Beispiel und da ist die Klasse schlicht nicht final. (Was ich nicht gut finde, denn eine Klasse sollte final sein. Aber hier ist es erst einmal schön, dass man so ein Beispiel findet.)

Ja sonst kann ich folgendes machen und die geerbte Klasse ist nicht mehr immutable;
Nein, wenn das Element private ist, dann kannst Du da keinen Wert in der abgeleiteten Klasse zuweisen.

Und die ganze Diskussion ist sinnlos. Es läuft also schlicht darauf hinaus: Wenn Du eine Klasse hast, mit der Du immutable Instanzen erzeugst, dann ist es ein Verstoß gegen Liskovs Substitution Principle, da sich die abgeleitete Klasse nicht mehr so verhält wie die Basisklasse. Und da spielt das final Schlüsselwort keine Rolle. Ich kann mit der final Klasse immer noch alles machen (wenn auch nicht mehr so einfach), wie Spring Framework und die Mockito Library zeigen (um zwei Beispiele zu bringen)

Und natürlich gibt es genug Quellen, die klar machen: So eine Klasse sollte final sein. Daher gibt es Blog Artikel, die das bei der Anleitung mitgeben (geeksforgeeks ist aber schlecht, die Formulierung ist aus meiner Sicht nicht ok. ("The class must be declared as final so that child classes can’t be created." - eben nicht! Das ist Anfänger Niveau wie es Tobias regelmäßig bringt, wo man einem Neuling ohne Begründung etwas als MUSS verkauft statt es vernünftig zu erläutern. Dann sollte etwas so sein aber Ausnahmen sind denkbar! Es geht um ein Verständnis!) Da finde ich dann Effective Java deutlich besser - klare Best Practices mit Erläuterung. Kann ic nur jedem empfehlen!)

Daher noch einmal ganz klar und deutlich: Wenn Ihr behauptet, etwas MUSS so sein, dann darf es unter keinen Umständen anders sein!

Das ist meine klare Sichtweise. Aber bestimmt habt Ihr da auch einfach mal ein paar Argumente?
 

KonradN

Super-Moderator
Mitarbeiter
Ach ja - wegen immutable class - das kann man natürlich 1:1 ebenso definieren. Dazu einfach aus Effective Java die folgende Definition:
An immutable class is simply a class whose instances cannot be modified. All of the information contained in each instance is fixed for the lifetime of the object, so no changes can ever be observed.

Mit der Definition ist es übrigens prinzipiell von der Definition her auch kein Problem, wenn man hat:
public class NonImmutable extends Immutable

Immutable erfüllt ohne final die Definition. NonImmutable würde diese Definition nicht erfüllen. Daher halt mein Hinweis auf das Liskovsche Substitutionsprinzip.
 

Blender3D

Top Contributor
Nein, wenn das Element private ist, dann kannst Du da keinen Wert in der abgeleiteten Klasse zuweisen.
Die Betonung hier liegt auf wenn. Jeder kann eine nicht finale Klasse benutzen und von dieser Klasse erben. Was daraus gemacht wird liegt nicht in der Hand des ursprünglichen Erstellers. Mittels final kann er das allerdings im Vorfeld unterbinden.

Bei Oracel findet man folgende Strategie für immutable Objekte.
https://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html
Daraus ergibt sich auch das die Klasse nicht zwingend final sein muss. Die Klasse muss aber verhindern, dass dann Unterklassen Methoden nicht überschreiben können.
Was somit @KonradN mit seinem Hinweis darauf bestätigt.
Siehe obigen Link unter Punkt 3)
Trotzdem wird das angeführte Beispiel als final Class gezeigt.
 

KonradN

Super-Moderator
Mitarbeiter
Die Betonung hier liegt auf wenn.
Ja, das ist richtig. Und ich denke, unter dem Strich sind wir alle hier durchaus einer Meinung oder liegen zumindest sehr dicht beieinander und wir reden teilweise leicht aneinander vorbei, weil vermutlich zwei Sichtweisen aufeinander Treffen:
Zum einen die Sichtweise: Wie sollte man eine immutable Klasse schreiben? Aus der Sicht kommen viele. Ich selbst hatte auf Grund der Posts #3 und #4 die Fragestellung: Was muss zwingend gegeben sein, damit man etwas als immutable bezeichnen kann?

Bezüglich diesem "wenn" macht es evtl. Sinn, da einfach einmal die Anforderungen zusammen zu fassen. Wie sollte eine immutable Klasse aussehen:

a) Keine Methoden anbieten, die den State verändern (Klar, Setter wären blöd)

b) final class -> Keine Ableitung erlauben, damit nicht eine nicht immutable Version übergeben werden kann, was dann zu Problemen führen kann.

c) Alle Felder final -> Initialisierung nur im Konstruktor möglich.

d) Alle Felder private -> Keine Veränderung außerhalb der Klasse möglich

e) Exklusiver Zugriff auf alle veränderlichen Komponenten. Man kann also gerne in der Klasse etwas vorhalten, das an sich verändert werden kann. Aber die Referenz kommt nicht von außen und wird auch nie nach außen gegeben. Also wenn man eine List hat, dann würde man nicht die Referenz von außen übernehmen sondern eine neue List erzeugen und die Elemente übernehmen. Ebenso wenn man es nach außen gibt.

Das findet sich an vielen Stellen beschrieben, u.a. im erwähnten Effective Java Buch aber auch im Link von @Blender3D in #10.
 

RennesVin

Mitglied
Und den Punkt haben wir dann ja jetzt wohl abgehakt, oder?
Da sind wir daccor.

Wenn jemand aber eine immutable Klasse schreiben möchte, also eine Klasse, deren Instanzen immutable sind, dann würde ich es nicht akzeptieren, wenn diese Klasse nicht den final Modifier hätte...

Aber wie auch richtig... da sind wir partiell bei Wortklauberei. Formulierungen sollten aber dennoch richtig sein. (Auch wenn jetzt ein Anfänger bzw eine Anfängerfrage mit den bisherigen Antworten überfordert sein könnte.) So, der Grill ruft
 

mrBrown

Super-Moderator
Mitarbeiter
Ich habe gerade folgende Aussage gelesen.


Das kann ich nicht so ganz glauben, denn:
Java:
String strValue = "Hallo";
        strValue = "Welt";

Oder was sagen andere dazu?
Zwar OT, aber warst du nicht vor kurzem noch Dozent für Java mit langjährige Berufserfahrung und hast dich über deiner Meinung zu niedrige Jobangebote beschwert? 🤨
 

Robert Zenz

Top Contributor

KonradN

Super-Moderator
Mitarbeiter
Ohne den Thread unnötig weiter führen zu wollen - ich bin da gerade durch Zufall über etwas stolpert als ich über den Source von BigInteger gekommen bin:
BigInteger vom Java Framework ist immutable und nicht final :)

jdk/BigInteger.java at master · openjdk/jdk · GitHub

(sehr stark verkürzter Auszug)
Java:
/**
 * Immutable arbitrary-precision integers.  All operations behave as if
 */

public class BigInteger extends Number implements Comparable<BigInteger> {
 

Robert Zenz

Top Contributor
Ohne den Thread unnötig weiter führen zu wollen - ich bin da gerade durch Zufall über etwas stolpert als ich über den Source von BigInteger gekommen bin:
BigInteger vom Java Framework ist immutable und nicht final :)

Macht ja auch Sinn, die beiden Konzepte sind ja zwei unterschiedliche Dinge. Eine unveraenderbare Klasse kann auch Subklassen haben, wohingegen eine Klasse welche nicht vererbbar sein soll ja durchaus veraenderbar sein kann. Zu sagen dass eine unveraenderbare Klasse immer final sein muss ist ja nicht richtig. Ein anderes Beispiel dafuer ist ja java.nio.Path, da steht in der Dokumentation der Schnittstelle:

Code:
 * <h2>Concurrency</h2>
 * <p> Implementations of this interface are immutable and safe for use by
 * multiple concurrent threads.

Wir koennen eben nicht den gesamten "API-Vertrag" in der Sprache selbst abdecken, manchmal muss man auch auf die Javadoc ausweichen (und darauf vertrauen dass der Verwender halt nicht dumme Dinge tut, oder dann zumindest nicht heulend ankommt).

Meine Meinung ist ja ohnehin dass private und final ueberbewertet werden, aber das ist wahrscheinlich irgendwie ein anderes Thema...
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
H Warum sind in Java Strings und Arrays eigentlich unveränderlich? Java Basics - Anfänger-Themen 2
W Gleichzeitiges ersetzen mehrerer Strings Java Basics - Anfänger-Themen 7
R Datentypen Das Verhalten von Strings als Datentypen Java Basics - Anfänger-Themen 7
N Nachkommastellen von Strings Java Basics - Anfänger-Themen 3
B Alle Strings bis zu einer Maimallänge aufzählen, die Bedingung erfüllen Java Basics - Anfänger-Themen 13
S Die durchschnittliche Länge der Strings Java Basics - Anfänger-Themen 11
M Operatoren Strings mit Vergleichsoperatoren, funktioniert das? Java Basics - Anfänger-Themen 9
S Variablen Letzte Zeile eines Strings entfernen Java Basics - Anfänger-Themen 1
D Strings aus Excel-Datei einlesen Java Basics - Anfänger-Themen 2
P9cman Tipps für Rekursive Aufgaben mit Strings oder allgemein Java Basics - Anfänger-Themen 2
sserio StringBuilder und Strings Java Basics - Anfänger-Themen 8
J Größe eines Strings in Pixel Java Basics - Anfänger-Themen 18
schredder Strings und reguläre Ausdrücke - Methode mit return string.matches Java Basics - Anfänger-Themen 5
B Konkatenieren eines Strings und inkremtierenden Zahl zu einer INT Variablen Java Basics - Anfänger-Themen 7
N Strings verpflechten Java Basics - Anfänger-Themen 4
G Strings auf Gleichheit prüfen - Aufgabe vom Prof. Java Basics - Anfänger-Themen 5
A 2 Strings vergleichen in einer methode wenn man mit Globalen variablen arbeitet Java Basics - Anfänger-Themen 12
L Strings aneinanderhängen Java Basics - Anfänger-Themen 2
M Strings vergleichen Java Basics - Anfänger-Themen 10
Nerdinfekt BMI Rechner, fehler beim Zurückgeben des Strings? Java Basics - Anfänger-Themen 2
U Problem mit dem initialisieren meines Strings in einer Schleife Java Basics - Anfänger-Themen 5
S 2 Strings mit Equals vergleichen Java Basics - Anfänger-Themen 11
Q Besitzen zwei Strings identische Buchstaben, nur in anderer Reihenfolge? Java Basics - Anfänger-Themen 10
marcooooo Separator zwischen allen Zeichen eines Strings einfügen Java Basics - Anfänger-Themen 29
C Ternärer Operator mit Strings Java Basics - Anfänger-Themen 3
M Wie kann ich bei int-Variablen im exception handler auf bestimmte Strings reagieren? Java Basics - Anfänger-Themen 5
P Verketten, Aneinanderreihen von Strings Java Basics - Anfänger-Themen 2
M Strings mit gerader und ungerader Länge ausgeben Java Basics - Anfänger-Themen 10
J Alle Werte eines Strings zusammen addieren Java Basics - Anfänger-Themen 15
W Strings und das parsen Java Basics - Anfänger-Themen 8
D Frage zu Strings einer Exception Java Basics - Anfänger-Themen 4
D Vergleichen von Strings Java Basics - Anfänger-Themen 6
M Konkatenation von zwei Strings Java Basics - Anfänger-Themen 6
J Abbruchbedingung in Schleife/ Untersuchung von Strings Java Basics - Anfänger-Themen 2
S Buchstaben in Großbuchstaben (Strings) Java Basics - Anfänger-Themen 5
X Anagramm mit Strings und Methode Java Basics - Anfänger-Themen 53
P geschachtelte Schleife mit Strings Java Basics - Anfänger-Themen 2
P Strings mit der Axt zerteilen Java Basics - Anfänger-Themen 7
F Alle Zeichenkombinationen eines Strings iterativ herausfinden Java Basics - Anfänger-Themen 26
K Strings hochzählen Java Basics - Anfänger-Themen 20
J Strings untereinander in einer Liste vergleichen Java Basics - Anfänger-Themen 18
B Frage zu: String... strings -> Ungleiche Anzahl an Parameter? Java Basics - Anfänger-Themen 4
F Vergleiche mit charAt funktioniert bei Strings nicht, was tun? Java Basics - Anfänger-Themen 5
T Probleme mit Strings Java Basics - Anfänger-Themen 6
J Unveränderbarkeit von Strings Java Basics - Anfänger-Themen 3
O Klammerung bei Strings Java Basics - Anfänger-Themen 10
A Liste aus drei Strings erstellen Java Basics - Anfänger-Themen 5
N Zwei Strings mit "==" vergleichen warum TRUE Java Basics - Anfänger-Themen 2
G Teil(e) eines Strings entfernen wenn spezifische Zeichen (< & >) vorkommen Java Basics - Anfänger-Themen 5
D ergebnis.matches("[1-9]?[0-9].[0-9][0-9]?") ein teil eines größeren Strings Java Basics - Anfänger-Themen 12
J Breite eines Strings bestimmen Java Basics - Anfänger-Themen 4
D Zwei Strings sind gleich bei if aber nicht true Java Basics - Anfänger-Themen 2
F JList Elemente mit Strings vergleichen Java Basics - Anfänger-Themen 12
J Strings sind gleich werden aber ungleich ausgewertet Java Basics - Anfänger-Themen 2
N Vergleich von Strings schlägt fehl.. Java Basics - Anfänger-Themen 5
B 4 Strings, Anfangsbuchstaben muss unterschiedlich sein Java Basics - Anfänger-Themen 12
P Strings in String Array schreiben Java Basics - Anfänger-Themen 13
J Input/Output Strings aneinander reihen mit while schleife Java Basics - Anfänger-Themen 25
B mir nur die Gesamtzahl von einzigartigen Strings aus Array ausgeben lassen Java Basics - Anfänger-Themen 5
R Erste Schritte Sicheres einlesen eines Strings Java Basics - Anfänger-Themen 2
F Maximale Länge eines Strings Java Basics - Anfänger-Themen 5
J Best Practice Datum Differenz aus zwei Strings ermitteln Java Basics - Anfänger-Themen 8
Jinnai4 Strings ersetzen Java Basics - Anfänger-Themen 9
R Übergeben eines Array Strings an einen Spinner Java Basics - Anfänger-Themen 4
L Rekursiv zwei Strings vergleichen Java Basics - Anfänger-Themen 3
L Prüfe, ob die im String Array enthaltenen Strings aufsteigend sind. Java Basics - Anfänger-Themen 19
J Algorithmus - Strings auf eigene Reihenfolge miteinander vergleichen Java Basics - Anfänger-Themen 4
DaCrazyJavaExpert Variablen Zahlen aus Strings auslesen Java Basics - Anfänger-Themen 4
C 2 Strings Java Basics - Anfänger-Themen 15
T befehle unterschiedlicher anzahl an strings wiedergeben Java Basics - Anfänger-Themen 2
JavaNewbie2.0 Strings in andere Klassen importieren. Java Basics - Anfänger-Themen 2
D BlueJ Java: Strings voneinander trennen Java Basics - Anfänger-Themen 11
javaerd Wie kann ich Brute Force Methode mit Strings erweitern Java Basics - Anfänger-Themen 1
R Erste Schritte Strings "einrücken" Java Basics - Anfänger-Themen 3
Yamie ArrayList<Object> als Liste von Strings ausgeben? Java Basics - Anfänger-Themen 15
B gemeinsames Vorkommen der charactere von 2 Strings als String zurückgeben Java Basics - Anfänger-Themen 5
R Teilinhalt eines Strings testen Java Basics - Anfänger-Themen 10
H Erste Schritte JTree: Instanzen einer Klasse speichern oder Namen/Strings... Java Basics - Anfänger-Themen 4
L Werte von Strings ? Java Basics - Anfänger-Themen 1
L Strings und Arrays - Expand Java Basics - Anfänger-Themen 12
I Schachbrett aus beliebigen Strings erstellen Java Basics - Anfänger-Themen 3
Syncopated Pandemonium Verketten von Strings funktioniert nicht Java Basics - Anfänger-Themen 4
F Wahrscheinlichkeit von Strings Java Basics - Anfänger-Themen 3
MiMa Splitten eines Strings Java Basics - Anfänger-Themen 5
T Hashfunktion für Strings Java Basics - Anfänger-Themen 3
C Zeilenumbruch für langes Strings Java Basics - Anfänger-Themen 2
J Variablen Strings mit Zeilenumbrüchen in neues Array Element Java Basics - Anfänger-Themen 1
T Datentypen compareTo() u. equals() bei Strings Java Basics - Anfänger-Themen 3
H Strings vergleichen & sortieren Java Basics - Anfänger-Themen 20
H Erste Schritte Längstes Wort eines Strings herausfinden Java Basics - Anfänger-Themen 7
D Problem beim umwandeln eines Strings in eine Dzezimalzahl Java Basics - Anfänger-Themen 6
G Strings mit Scanner (nextLine) einlesen Java Basics - Anfänger-Themen 7
T Strings ersetzen mit \ Java Basics - Anfänger-Themen 10
K Strings bearbeiten Java Basics - Anfänger-Themen 14
N Bestimmte Zeichen eines Strings umwandeln Java Basics - Anfänger-Themen 4
L Java Strings Buchstaben vertauschen Java Basics - Anfänger-Themen 4
L Strings in einem JOptionPane farbig Java Basics - Anfänger-Themen 2
A Wie bekomme ich zwei Strings in eine ArrayList Java Basics - Anfänger-Themen 4
C Chars eines Strings mit for schleife rückwärts auslesen Java Basics - Anfänger-Themen 8
J Buchstabe (char) an zufällige Position eines Strings einfügen Java Basics - Anfänger-Themen 1

Ähnliche Java Themen

Neue Themen


Oben