| 

.NET C# Java Javascript Exception

9
In Java sind Strings immutable bzw. unveränderlich. Warum? Ist das auch in anderen Sprachen so?
News:
27.10.2009
ermin 1,3k 2 7
ermin 1,3k 2 7
6 Antworten
8
Es ist auch in .net so.

Eine ausführliche Behandlung dieses Themas bietet Why can’t string be mutable in java and .net.
27.10.2009
gfoidl 9,4k 3 5
1
Strings sollen sich so wie andere elementare Datentypen verhalten. So wie das Integer-Literal 3 nicht einen anderen Wert bekommen kann (war unter Fortran damals noch möglich, um nicht immer π voll ausschreiben zu müssen), so kann man den Wert eines Strings nicht ändern.

Keys in einer Map dürfen sich nicht ändern, da ansonsten der Hash inkonsistent wird und nichts davon mitkriegt.

Und in der funktionalen Programmierung werden Instanzen eh meistens nur erzeugt und nicht verändert.
26.05.2011
theorist 494 6
Für Keys innerhalb einer Map gilt das auch für andere Objekte, zumindest für die equals-Attribute. Der Wunsch ist es, dass sich die Attribute, die über equals verglichen werden, nie ändern. Für hashCode ist es nicht nur ein Wunsch, sondern ein Muss.

Du hast teilweise Recht mit der funktionalen Programmierung. Mit der Einführung von Referenzen hast Du das Problem der Seiteneffekte durch Veränderlichkeit auch dort. Zeichenketten sind sinnvollerweise, in den Programmiersprachen, die ich bisher verwendet habe, davon ausgeschlossen.
oopexpert 01.06.2011
Ich habe mit konstanten Strings kein Problem. Genausowenig, wie ich mit konstanten ints ein Problem habe. In richtigen OO-Sprachen, wie Smalltalk, sind ints auch Objekt-Instanzen und können nicht verändert werden.

Ich finde die Argumentation bei stackoverflow schön: anstatt zu hinterfragen, ob ein Objekt immutable sein muss, sollte mehr Wert darauf gelegt werden, ob es unbedingt mutable sein muss!

Ich kein Deiner Argumentation nicht ganz folgen: nicht nur der Hashcode muss konstant bleiben, sondern auch der Equals-Operator, wenn als Map z.B. eine sortierte Liste verwendet wird.
theorist 01.06.2011
0
public class IchbinString{
public static void main(String args[]){
String s1 = new String("Hallo");
String s2 = new String("Du");
System.out.println(s1);
s1=s2;
System.out.println(s1);
}
}


Schau dir den Code mal an. Wenn Strings wirklich unveränderlich wären, dann sollte s1 "Hallo" ausgeben, aber wie du siehst gibt das zweite Output "Du" aus... Also sind Strings nicht so wirklich immutable ;)
28.10.2009
Forlan 177 1 5
Forlan 177 1 5
2
Doch sind sie :)
Bei der Anweisung s1=s2 wird von der Runtime eine neue Instanz von s1 erstellt und dieser Instanz der Wert von s2 zugewiesen.
Jetzt verliert die erste Generation von s1 seine Gültigkeit und kommt auf die Liste des GC zum entsorgen.
Also doch immutable ;)
klaus_b 28.10.2009
Strings, die mit "new String("")" erzeugt werden, liegen zwar nicht im JVM String Pool, aber verändern kannst die ein so erzeugtes String-Objekt trotzdem nicht oder wie willst du aus dem "Hallo" Objekt ein "Hallo 2" Objekt machen, ohne ein neues Objekt zu erzeugen?
jenser78 28.10.2009
1
@klaus_b:
Fast korrekter Kommentar ;)
In .net (und wie ich dem oberen Kommentar von jenser78 entnehme auch in Java) liegen die Strings in einem Pool und somit wird bei s1 = s2 nur der Verweis von s1 auf den Inhalt von s2 gesetzt, jedoch kein neues Objekt für s1 erstellt. Das ist möglich da auch s2 immutable ist.

Dies ermöglich auch die Strings als 'interned' zu vergleichen was u.U. sehr schnell sein kann ;)
gfoidl 28.10.2009
@gfoidl
In den String Pool gelangen nur Strings, die nicht mit "new" erzeugt wurden. Wenn man sich dessen nicht bewußt ist (ging mir am Anfang so) kommt es oft zu Fehlern, die man nicht versteht. Zum Beispiel:

String s1 = "Hallo";
String s2 = "Hallo";

"s1 == s2" liefert hier "true", weil beide auf den selben String im Pool referenzieren, aber bei:

String s1 = "Hallo";
String s2 = new String("Hallo");

liefert s1 == s2 "false", weil "new" wirklich ein Objekt außerhalb des Pool erzeugt nur die Referenzen verglichen werden. Strings sollten immer nur mit equals() verglichen werden.
jenser78 28.10.2009
@jenser78: Bezieht sich dein Kommentar auf Java und/oder .net?
In Java glaube ich deinem Kommentar da ich von Java keine Ahnung habe.
In .net ist es so wie ich oben kommentiert habe.

Aber Danke für den Hinweis dass das in Java nicht so ist.
gfoidl 28.10.2009
@gfoidl
Da die ursprüngliche Frage Java betraf und ich nicht wusste ob es in Java auch einen String-Pool gibt, hab ich ihn aussen vor gelassen. Das das String-Objekt ein ganz besonderer Zeitgenosse ist, wollte ich die Erklärung einfach halten.
Ein Fehler wie sich im nach hinein herausstellte :-P
klaus_b 28.10.2009
@gfoidl
Bezieht sich nur auf Java, da ich von .net keine Ahnung habe ;-)
jenser78 28.10.2009
@klaus_b: Ich hab ja gewusst dass du das weißt ;) Die String-Klasse ist wirklich besonders mit ihren Eigenheiten ;)
gfoidl 28.10.2009
Es gibt KEINEN Anwendungsfall, wo ein Objektvergleich (s1 == s2) für Strings sinnvoll wäre. Da sollte man immer die Equals-Methode heranziehen. Deshalb stellen sich mir diese Fragen zu den Eigenarten der String-Klasse nicht. String ist ein Klasse, und Objekte einer Klasse vergleicht man mit equals.
oopexpert 25.05.2011
@oopexpert: String ist keine normale Klasse, sondern hat Wertsemantik, d.h. sie verhält sich wie eine Struktur. Insofern sind die Besonderheiten davon schon wichtig zu wissen.
gfoidl 25.05.2011
0
Bitte löschen. Sollte ein Kommentar werden
28.10.2009
klaus_b 1,6k 3 7
klaus_b 1,6k 3 7
0
Wären Strings in Java veränderlich, hätte man keine Sicherheit was den drinnen steckt.
Dann würde Java so etwas wie bei C++ Zeiger besitzen, und das wollten die Designer von Java nicht haben.

z.B.

String hallo ="Hallo";

methode (hallo);
System.out.println (hallo);

...

void methode (String para)
{
para.set("Tschüss"); // gibt es nicht
}


Wenn man aber ein solches Verhalten haben will, kann man es auch in Java erzielen.
z.B.
class MutableString
{
private String wert;
public void set (String pWert) {wert= pWert;}
public String get () {return wert;}
}
...
MutableString ms = new MutableString ();
ms.set ("Hallo");
methode (ms);
System.out.println (ms.get ());

...

void methode (MutableString para)
{
para.set("Tschüss"); // Das geht
}
01.11.2009
stefan.bachert 395 4
0
Strings sind immutable, weil man bei solch einem Quasi-primitiven Datentyp, der fast überall verwendet wird, keine Seiteneffektbehandlung (references, multi-threading) möchte.
25.05.2011
oopexpert 455 1 8

Stelle deine .net-Frage jetzt!