Datentypen Das Verhalten von Strings als Datentypen

robinkognito

Mitglied
Hey, ich hätte da mal eine kurze Frage zu Strings:

In unterschiedlichen Kursen habe ich gelernt, dass es sich bei Strings nicht um primitive Datentypen sondern um Referenz-Datentypen handelt, die nicht unmittelbar den Wert speichern, sondern lediglich eine Angabe darüber enthalten, wo sich der Wert im Speicher befindet.

Mir ist nun im Vergleich mit primitiven Datentypen und anderen Referenz-Datentypen aufgefallen, dass Strings sich mal eher wie die einen und dann doch wieder wie die anderen verhalten.

Beispiele dafür:
Erstelle ich eine Array-Variable, habe ich einen "klassischen" Referenz-Typen. Wenn meinen Array-Wert in eine Methode einsetze und die Methode auf ihn zugreift, wird für die Methoden-Variable der Wert des Arrays kopiert - in diesem Fall nur die Referenz, die in der Variable gespeichert ist. Manipuliere ich nun mit der Methode meine Methoden-Variable, ändert das auch die Werte der Ursprungsvariable, da beide Variablen auf dasselbe Array zugreifen. Bei primitiven Datentypen befindet sich hingegen der Wert direkt "in" der Variable und meine Methode kann die Ursprungsvariable nicht manipulieren, da es sich ja nur um eine Kopie dieses Wertes handelt.

Nun haben wir die String-Variable, die sich aber genau wie ein primitiver Datentyp verhält und sich nicht verändert, obwohl es ein Referenz-Typ ist?


1710271589898.png
1710271633869.png


Nun eine andere Situation: Ich will ein Conditional Statement aufbauen. Primitive Datentypen kann ich dann einfach in meinem Statement durch Vergleichsoperationen wie >, ==, ... miteinander vergleichen. Will ich nun aber einen String verwenden, brauche ich die .equals() Funktion, damit dies funktioniert und die String-Variable verhält sich nicht mehr wie ein primitiver Datentyp.

Kann mir hier jemand erklären, was es mit Strings auf sich hat und wo die nun einzuordnen sind? :D
 

KonradN

Super-Moderator
Mitarbeiter
Ich denke, dass Du da noch ein paar Dinge durcheinander wirfst. Bei Methoden hast Du generell eine Übergabe per Wert. Das bedeutet, dass nur der Inhalt der Variable (Also der Wert bei einem Value Type und die Referenz bei einem Referenz Typ) kopiert wird.

Das heisst, bei einer Zuweisung ist immer nur der Parameter betroffen und nicht die original Variable. Bei dem Array Beispiel wäre das aber ein:
Java:
public static void someMethod(ArrayList<String> parameter) {
    parameter = new ArrayList<String>();
    // ...
}

Dieses Verhalten ist also unabhängig vom Typ des Parameters und nennt sich oft "Call by Value" und bedeutet, dass diese Zuweisung sozusagen nur eine Kopie betrifft.

Was Du aber auch noch etwas ansprichst, ist das, was man oft als mutable und immutable, also veränderlich und unveränderlich bezeichnet.

Werte eines Wertetyps sind unveränderlich. Eine 1 ist immer eine 1. Du kannst aus einer 1 nichts anderes machen. Alles, was Du machen kannst, ist ein neuen Wert zuweisen.
Du kannst aber auch entsprechende Klassen schreiben. Dann kannst Du diese nur einmalig initialisieren und dann gibt es keine Möglichkeit mehr, den Zustand zu ändern. Beispiele hierfür sind z.B. die Wrapper-Klassen (Integer, Double, ...) und auch String. Ebenso die Records, die vor nicht zu langer Zeit eingeführt wurden und eine spezielle Klasse darstellt, ist ebenso unveränderlich.

Wenn eine Klasse mutable ist (wie z.B. die ArrayList), dann kannst Du natürlich eine Referenz beim Aufruf der Methode kopieren (Call by Copy) und dann über die Referenz die Instanz verändern.

Bildlich kann man dies evtl. so darstellen:

Methodenaufruf: Das ist wie ein Anruf. Da kann jemand Dir vorlesen, was auf Zetteln steht (Parameter). Das schreibst Du dann das, was Dir gesagt wird, auf Zettel bei Dir. Damit hast dann Kopien der Zettel (=> Call by Value)

Zuweisung: Du kannst dann natürlich auf Deinen Zetteln das aufgeschriebene streichen und dann etwas Neues auf den Zettel schreiben. Dadurch ändert sich aber nicht der original Zettel beim Anrufer.

Referenzen: Du hast da dann halt Adressen. Und du kannst zu der Adresse fahren und etwas machen. Wenn da ein Haus ist, dann kannst Du damit was machen. Du streichst das Haus z.B. an. Jeder, der die Adresse hat, kann also jetzt zum Haus fahren und sehen: Das Haus ist neu angestrichen.

Immutable: Jetzt gibt es aber auch Adressen, die führen zu Objekten, die kannst Du nicht verändern. Du kannst mit dem Objekt nichts machen, also auch nicht das Objekt wegnehmen und mit etwas anderem ersetzen oder so.

Hat das etwas beim Verständnis geholfen und die Problematik etwas aufgeklärt?

Edit: unmutable -> immutable (Danke für den Hinweis @httpdigest)
 
Zuletzt bearbeitet:

robinkognito

Mitglied
Hat das etwas beim Verständnis geholfen und die Problematik etwas aufgeklärt?
Hey, erst mal vielen Dank für deine umfangreiche Antwort. Das hat nochmal einiges für mich sortiert. :D

Eins verstehe ich jedoch noch nicht:
Wenn ich die "Adresse" eines Strings, der mich zum Objekt führt, als Parameter an eine Methode übergebe, wird diese kopiert. Nun habe ich eine Kopie der Adresse und meine Methoden-Variable sollte mich auch zu dem Objekt führen, zu dem mich die andere String Variable führt. An dem Wert des Objekts kann ich innerhalb der Methode aber nichts verändern, weil dieses immutable ist - soweit korrekt?

Nun verhält sich das Objekt aber nicht, wie ich hier probiert habe zu schlussfolgern, sondern doch ganz anders.

Im Bild mal als Beispiel, was ich meine:

Die Variable String test enthält die Adresse, die mich zu dem Objekt mit dem Wert "dasisteintest" führt.
Benutze ich test nun als Parameter für eine Methode, wird die Adresse von test in die Methoden-Variable String hey kopiert.

Nun sollte die Variable hey eine Kopie der Adresse enthalten, mich somit zu dem Objekt mit dem Wert "dasisteintest" führen.
Da Strings immutable sind(?), sollte ich dann an dieser Stelle nichts am Wert des Objekts "dasisteintest" verändern können.
Probiere ich das aber, stelle ich fest, dass ich einerseits den Wert des Objekts doch verändern kann und andererseits der Wert des Strings test erhalten bleibt, ich somit 2 verschiedene Strings habe.

Es muss also ein weiteres Objekt angelegt worden sein und darüber hinaus auch eine neue Referenz, da mich die Variable hey nicht zu einem zweiten Objekt führen könnte, wenn sie eine Kopie der Referenz aus test wäre.
Wird hier also automatisch von Java beides neu angelegt und der Wert des ersten Objekts in das neue Objekt kopiert?
 

Anhänge

  • Screenshot 2024-03-13 192748.png
    Screenshot 2024-03-13 192748.png
    11,8 KB · Aufrufe: 0
Zuletzt bearbeitet:

mihe7

Top Contributor
Die Variablen bzw. Parameter befinden sich an unterschiedlichen Adressen im Speicher. Sagen wir mal test steht an Adresse 1000 und hey an 2000.

Jetzt gehen wir das mal durch:
  1. Es wird ein String-Objekt angelegt für "dasisteintest", sagen wir mal an Adresse 3000.
  2. Die Adresse des String-Objekts wird in Variable test gespeichert, d. h. im Speicher findet sich an Adresse 1000 der Wert 3000.
  3. Es wird die Methode methode aufgerufen, dabei wird der Wert der Variablen test in den Parameter hey kopiert, d. h. im Speicher wird der an Adresse 1000 abgelegte Wert (3000) nach Adresse 2000 (Adresse des Parameters hey) kopiert.
  4. In der Methode methode wird ein neues String-Objekt "neu" angelegt, sagen wir an Adresse 4000.
  5. Die Adresse des String-Objekts wird der Varaiblen hey zugewiesen, d. h. im Speicher wird an Adresse 2000 (Adresse des Parameters hey) der Wert 4000 gespeichert.
Auch, wenn das stark vereinfacht und nicht korrekt wiedergegeben ist (tatsächlich läuft das über einen Stack), hoffe ich mal, dass die Sache nun klarer geworden ist.
 

robinkognito

Mitglied
Die Variablen bzw. Parameter befinden sich an unterschiedlichen Adressen im Speicher. Sagen wir mal test steht an Adresse 1000 und hey an 2000.

Jetzt gehen wir das mal durch:
  1. Es wird ein String-Objekt angelegt für "dasisteintest", sagen wir mal an Adresse 3000.
  2. Die Adresse des String-Objekts wird in Variable test gespeichert, d. h. im Speicher findet sich an Adresse 1000 der Wert 3000.
  3. Es wird die Methode methode aufgerufen, dabei wird der Wert der Variablen test in den Parameter hey kopiert, d. h. im Speicher wird der an Adresse 1000 abgelegte Wert (3000) nach Adresse 2000 (Adresse des Parameters hey) kopiert.
  4. In der Methode methode wird ein neues String-Objekt "neu" angelegt, sagen wir an Adresse 4000.
  5. Die Adresse des String-Objekts wird der Varaiblen hey zugewiesen, d. h. im Speicher wird an Adresse 2000 (Adresse des Parameters hey) der Wert 4000 gespeichert.
Auch, wenn das stark vereinfacht und nicht korrekt wiedergegeben ist (tatsächlich läuft das über einen Stack), hoffe ich mal, dass die Sache nun klarer geworden ist.
Ist es, vielen Dank!
 

KonradN

Super-Moderator
Mitarbeiter
Das ist soweit alles korrekt wieder gegeben.

Ich versuche einmal, Deinen Code etwas bildlich darzustellen.

In Deinem Code hast Du zwei sogenannte String Literale - die müssen also auch im Programm drin sein. Du hast also innerhalb Deines Code auf den Speicherplätzen S1 und S2 die beiden Strings:

S1: "dasisteintest"
S2: "neu"

Im Laufe Deines Programmes hast Du dann die Variable test. Diese bekommt jetzt eine Referenz auf einen Speicherplatz - und zwar den von S1. Du hast also:
test := REF(S1).

Dann wird die Methode aufgerufen. Daher wird der Inhalt der Variable test (Das "REF(S1)") kopiert und Du hast:
hey := REF(S1)

Die Variable kannst Du aber anpassen - das machst du in der Methode. hey wird nun eine Referenz auf S2 zugewiesen. Daher hast Du dann
hey := REF(S2)

Das ändert dann - so wie Du siehst - nicht den Inhalt von test - das hat weiterhin REF(S1).

String ist immutable. Das bedeutet, dass Du den Text "dasisteintest" in S1 nicht ändern kannst. Du kannst also nicht sagen: Das erste "d" soll ein "w" werden ("wasisteintest"). Das geht zumindest mit Java Mitteln nicht.

Machen wir ein Beispiel mit einer anderen Klasse:


Java:
public class Test {
    public int value;
}

Jetzt kannst Du auf einer Speicherstelle S3 eine Instanz von Test haben. Also z.B. etwas wie:
S3: Test(value=1);

Nun kannst Du auch eine Variable haben mit einer Referenz:
var := REF(S3)
und dies kannst Du als Parameter param übergeben. Dann hast Du:
param := REF(S3)

Nun kannst Du in der Methode param nutzen um value der Instanz Test auf 2 zu setzen. Damit hast Du an Speicherstelle S3:
S3: Test(value=2)

Die Variable var ist aber unverändert immer noch REF(S3). Aber das, was am Speicherplatz S3 gespeichert ist, hat sich geändert.

Hat diese bildliche Darstellung noch etwas weiter geholfen?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
MarvinsDepression Operatoren Verhalten von BitShiftOperatoren Java Basics - Anfänger-Themen 2
G Merkwürdiges Verhalten der Maven IDE Java Basics - Anfänger-Themen 3
D Unerwartetes Verhalten bei Client Server Chat App Java Basics - Anfänger-Themen 12
B Programm beendet sich nicht und weiteres seltsames Verhalten Java Basics - Anfänger-Themen 9
G unklares Verhalten nach Instanzierung neuer Klasse Java Basics - Anfänger-Themen 3
MiMa Seltsames Verhalten im Konstruktor Java Basics - Anfänger-Themen 6
M Komisches Verhalten der Variablen Java Basics - Anfänger-Themen 6
K Klassen Eclipse Verhalten bei Klassen Java Basics - Anfänger-Themen 16
M Verhalten von LocalDateTime#getNano() Java Basics - Anfänger-Themen 1
T Objekte mit Verhalten Java Basics - Anfänger-Themen 14
D Klassen Verhalten von Klassenvererbung bei Variablen Java Basics - Anfänger-Themen 1
D Seltsames Verhalten... Java Basics - Anfänger-Themen 5
O JFileChooser Verhalten -Pfad Java Basics - Anfänger-Themen 15
S Verhalten von JTextField in einem JTabbedPane (Register) Java Basics - Anfänger-Themen 6
G Input/Output Verhalten BuffferedReader bei unvollständigen Zeichen Java Basics - Anfänger-Themen 1
D Interface für Verhalten von "=="? Java Basics - Anfänger-Themen 21
B Thread komisches Verhalten auf Mac ... Java Basics - Anfänger-Themen 6
B Komisches Verhalten von ArrayList Java Basics - Anfänger-Themen 6
S JInternalFrame in JInternalFrame - Verhalten Java Basics - Anfänger-Themen 2
F Nicht nachvollziehbares Verhalten Java Basics - Anfänger-Themen 7
K Komisches Verhalten beim erstellen einer Datei Java Basics - Anfänger-Themen 5
T unerklärliches Verhalten von Scanner Java Basics - Anfänger-Themen 2
Ham Verhalten beim Initialisieren von Arrays Java Basics - Anfänger-Themen 16
D Komisches Verhalten einer For-Schleifen Java Basics - Anfänger-Themen 7
zilti Unlogisches Verhalten Java Basics - Anfänger-Themen 4
N public void und verhalten bei return Java Basics - Anfänger-Themen 2
A Seltsames Verhalten beim ButtonClick (ActionListener() ) Java Basics - Anfänger-Themen 7
P Komisches Verhalten von BufferedReader und readLine() Java Basics - Anfänger-Themen 2
W Gleichzeitiges ersetzen mehrerer Strings Java Basics - Anfänger-Themen 7
N Nachkommastellen von Strings Java Basics - Anfänger-Themen 3
T Strings unveränderlich???? Java Basics - Anfänger-Themen 22
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

Ähnliche Java Themen

Neue Themen


Oben