2009-12-24 7 views
12

Ich habe gelesen, dass in Java ein Objekt des Typs String nicht ändern kann. Aber int und char Variablen können. Warum ist es? Kannst du mir ein Beispiel geben?String kann nicht geändert werden. Aber int, char kann ändern

Vielen Dank. (Ich bin ein neuerer -_-)

+2

Was meinst du, kann nicht ändern? Wie wäre es, wenn Sie uns ein Beispiel dafür geben, was Sie beschreiben? – user151841

+2

Willkommen bei SO. Ich denke, Sie müssen etwas beschreibender sein, um eine konstruktive Antwort zu erhalten. :) –

+9

ich verstehe nicht, warum diese Jungs einen Downvote bekommen. Er ist ein Neuling und stellt einfach eine Frage. Indem Sie nach unten stimmen, entmutigen Sie ihn. und ich kann nicht sehen, was mit der Frage falsch ist, es ist eine gültige! –

Antwort

18

Wie Bzabhi sagte, sind Strings in Java unveränderlich. Dies bedeutet, dass sich ein String-Objekt niemals ändert. Dies bedeutet nicht, dass Sie String-Variablen nicht ändern können, nur dass Sie die zugrunde liegende Speicherdarstellung der Zeichenfolge nicht ändern können. für ein Beispiel:

String str = "Hello"; 
str += " World!"; 

Nach der Ausführung dieser Zeilen zeigt str auf eine neue Zeichenfolge im Speicher. Die ursprüngliche Zeichenfolge "Hello" ist immer noch im Speicher vorhanden, wird aber höchstwahrscheinlich nicht lange verfügbar sein. Unter der Annahme, dass es keine mildernden Umstände gibt, wird nichts auf die ursprüngliche Zeichenkette zeigen, so dass es Müll gesammelt wird.

Ich denke, der beste Weg, um dies zu setzen wäre zu sagen, dass wenn Zeile 2 des Beispiels ausgeführt wird, eine neue Zeichenfolge im Speicher aus der Verkettung der ursprünglichen Zeichenfolge und der Zeichenfolge hinzugefügt wird. Die Variable str, die nur eine Referenz auf einen Speicherort ist, wird dann so geändert, dass sie auf die neue Variable zeigt, die gerade erstellt wurde.

Ich bin nicht besonders sachkundig in dem Punkt, aber, wie ich es verstehe, das ist, was mit allen "nicht-primitiven" Werten passiert. Alles, was zu einem bestimmten Zeitpunkt von Object abgeleitet wird, folgt diesen Regeln. Primitive Werte wie Ints, Bool, Chars, Floats und Doubles erlauben die Änderung des aktuellen Wertes im Speicher. Also, von diesem:

int num = 5; 
num += 2; 

der tatsächliche Wert im Speicher ändert sich. Anstatt ein neues Objekt zu erstellen und die Referenz zu ändern, ändert dieses Codebeispiel einfach den Wert im Speicher für die Variable num.

Warum das so ist, ist nur eine Designentscheidung der Hersteller von Java. Ich bin mir sicher, dass jemand kommentieren wird, warum das gemacht wurde, aber das weiß ich nicht.

+0

* Warum? * Ich rate nur hier, aber es ist wahrscheinlich, weil, wenn Sie eine Zeichenfolge erweitern müssten Sie Speicher sowieso neu zuordnen müssen. Die Zeichen werden zusammenhängend gespeichert, und das folgende Zeichen ist möglicherweise nicht verfügbar, so dass es einfach einen neuen Speicherabschnitt neu zuordnet. – mpen

+0

d. H. Es ist auf diese Weise (in den meisten Fällen) nur effizienter. Es sei denn, Sie möchten riesige Zeichenfolgen nur für den potenziellen Gebrauch zuweisen. Aber dafür ist StringBuffer ... – mpen

+0

(Ich würde 'int' mit' Integer' vergleichen - sie verhalten sich sehr ähnlich. 'AtomicInteger' und' StringBuilder' zum Beispiel verhalten sich ganz anders als 'Integer' /' int 'und' String'.) –

9

int und char kann auch nicht ändern. Wie bei Strings können Sie einen anderen Wert in die gleiche Variable eingeben, aber eine ganze Zahl ändert sich nicht. 3 wird immer 3 sein; Sie können es nicht ändern, um 4 zu sein.

3

Ich bin nicht sicher, dass es möglich ist, (durch Beispiel) zu zeigen, dass Zeichenfolgen nicht ändern können. Aber Sie können dies bestätigen, indem Sie den Abschnitt "Beschreibung" von Javadoc for the String class lesen, dann den Abschnitt "Methoden" lesen und feststellen, dass es keine Methoden gibt, die einen String ändern können.

BEARBEITEN: Es gibt viele Gründe, warum Strings in Java unveränderbar sind. Der wichtigste Grund ist, dass unveränderliche Zeichenfolgen einfacher zu verwenden sind als änderbare Zeichenfolgen. Und wenn Sie aus irgendeinem Grund das änderbare Äquivalent eines Strings benötigen, können Sie die StringBuilder (oder StringBuffer) -Klasse verwenden.

4

String ist ein unveränderlicher Typ (der Wert in der es nicht ändern kann). Dasselbe gilt für alle primitiven Typen (Boolean, Byte, Char, Short, Int, Long, Float und Double).

int x; 
String s; 

x = 1; 
x = 2; 
s = "hello"; 
s = "world"; 
x++; // x = x + 1; 
x--; // x = x - 1; 

Wie Sie sehen können, kann in keinem Fall ändern Sie den konstanten Wert (1, 2, „Hallo“, „Welt“), aber Sie können ändern, wo sie zeigen (wenn Sie Ihren Verstand ein wenig verziehen und sagen, dass eine int-Variable auf einen konstanten int-Wert zeigt).

2

Es ist auch wichtig zu beachten, dass Zeichenketten unveränderlich sind, dass sie, wenn sie an eine Methode übergeben werden, nicht innerhalb der Methode geändert werden können und diese Änderungen außerhalb des Methodenbereichs angezeigt werden.

public void changeIt(String s) { 
    // I can't do anything to s here that changes the value 
    // original string object passed into this method 
} 

public void changeIt(SomeObject o) { 
    // if SomeObject is mutable, I can do things to it that will 
    // be visible outside of this method call 
} 
1

Zeichenfolgen sind unveränderlich in java. Nichtsdestotrotz können Sie immer noch Werte an Strings anhängen oder voreilen. Mit Werten meine ich primitive Datentypen oder andere Strings.

Ein StringBuffer ist jedoch änderbar, d. H. Er kann im Speicher geändert werden (ein neuer Speicherblock muss nicht zugewiesen werden), was ihn ziemlich effizient macht. Bedenken Sie auch das folgende Beispiel:

StringBuffer mystringbuffer = new StringBuffer(5000); 

for (int i = 0; i<=1000; i++) 
{ 
    mystringbuffer.append ('Number ' + i + '\n'); 
} 

System.out.print (mystringbuffer); 

Anstatt die Schaffung eintausend Strings schaffen wir ein einzelnes Objekt (mystringbuffer), die in der Länge ausdehnen kann. Wir können auch eine empfohlene Anfangsgröße festlegen (in diesem Fall 5000 Byte), was bedeutet, dass der Puffer nicht ständig Speicher anfordern muss, wenn eine neue Zeichenfolge an ihn angehängt wird.

Während eine StringBuffer wird nicht die Effizienz in jeder Situation verbessern, wenn Ihre Anwendung Strings verwendet, die in der Länge wachsen, wäre es effizient. Der Code kann auch klarer mit StringBuffer s sein, weil die Append-Methode Sie daran hindert, lange Zuweisungen zu verwenden.