# Speicheradresse verändern



## b1zarRe (30. Apr 2012)

Hi,

ich weiß leider nicht, wie ich die Frage konkret stellen kann, da mir die Aufgabe dazu abhanden gekommen ist... es war aber sowas ähnliches wie das hier(evtl. auch eher mit Objekten und nicht elementaren Datentypen):


```
public class Speicheradresse {
    
    public static void main(String[] args) {
        
        // Erzeugen von 2 Variablen
        int a = 10;
        int b = 10;
        
        // Speicheradresse veraendern
        a = b;
        System.out.println("a = " + a);
        System.out.println("b = " + b);
        System.out.println("");
        
        // Inkrementieren
        a++;
        System.out.println("a = " + a);
        System.out.println("b = " + b);
        System.out.println("");
        
    }
}
```

Es geht prinzipiell darum, dass 2 Variablen instanziiert wurden und es eine Zeile in der Art von "a=b" gab(sprich: eine Variable hat von nun an auf eine andere gezeigt) und die Ausgabe war dann überraschend/unerwartet... Weiß jemand evtl. wovon ich da spreche??? Ich bräuchte da ein Beispiel..., weil leider bei diesem hier nichts ungewöhnliches ausgegeben wird...

Ich danke euch!


----------



## Hinki (30. Apr 2012)

Hallo

a=b bedeutet nicht a zeigt auf b, sondern a wird der Wert von b zugewiesen. int ist ein primitiver Datentyp.
Link


----------



## b1zarRe (30. Apr 2012)

@Hinki
Sorry, denke Du hast mich falsch verstanden... also mir ist klar, dass a der Wert von b zugewiesen wird... 

ich meinte nur, dass
es so einen "ähnlichen" Quellcode mal als Aufgabe hatte nur wie oben beschrieben wohl nicht mit elementaren/primitiven Werten, und da auch sowas in der Art stand wie a=b (nur ist hier a noch b wohl kein int gewesen) und sich dadurch irgendwie wohl der Zeiger geändert hatte..


----------



## Volvagia (30. Apr 2012)

Dann zeigt a und b auf die selbe Instanz. Ist ja klar, sie kann sich nicht einfach so "doppeln". Allerdings halte ich die Wahrscheinlichkeit für sehr gering, dass hier jemand das Beispiel kennt.


----------



## Dekker (30. Apr 2012)

Speicheradressen ändern ist in Java nicht möglich. Bist du dir sicher das du das nicht mit c/c++ verwechselst? 

Oder meinst du die Referenzen auf ein Objekt? Dabei handelt es sich allerdings nicht um direkte Speicheradressen sonderen um "Objektadressen" wenn man so will.


----------



## Blackhole16 (30. Apr 2012)

Ich vermute auch, dass es sich da um Objekte, wahrscheinlich ums Strings gehandelt hat...

Damit wäre Das Ergebnis natürlich erstaunlich, wenn man sich vorher nur mit primitiven Datentypen auseinandergesetzt hat. Aber wahrscheinlich war da nicht 
	
	
	
	





```
"a= " +a
```
 sondern eher 
	
	
	
	





```
String1 == String2
```
. Und dann wahrscheinlich so nach dem Motto: Was macht den Unterschied zwischen 
	
	
	
	





```
String s = "text";
```
 und 
	
	
	
	





```
String s = new String("text")
```
 und 
	
	
	
	





```
String1 = String2
```
 und 
	
	
	
	





```
String1 = new String(String2)
```

Wenn man all dies in so einem Programm wie oben zusammenbastelt, kommt da schon was komisches raus 

mfg
BH16


----------



## b1zarRe (30. Apr 2012)

Danke schonmal für die Bemühungen... ich habe nun doch die Aufgabe nach längeren Suchen gefunden:


```
public class Test {
    
    public static void main(String[] args) {
        
        Hashtable ht = new Hashtable();
        ArrayList v0 = new ArrayList();
        ArrayList v2;
        
        v0.add("a");
        ht.put("A", v0);
        
        v2 = v0;
        v2.add("b");
        
        ht.put("C", v2);
        
        System.out.println(ht.get("A").equals(ht.get("C")));
        System.out.println("");
    }
}
```

Ich verstehe einfach nicht warum hier true ausgeben wird :/
Habe es schon mit logischem Denken und Zeichnen probiert... verstehe es eifnach nicht. Hat wohl
was mit Referenzen zu tun.... anscheinend hakt es da noch bei mir...


----------



## timbeau (30. Apr 2012)

Erst wird v0 hinzugefügt, dann wird v2 die v0 zugewiesen und "v2" hinzugefügt, das aber v0 ist.


----------



## b1zarRe (30. Apr 2012)

Ich verstehe leider nicht, warum in Zeile 12/13 dann nicht v2 die Strings "a" sowie "b" drin hat und anscheinend nur "a" ???


----------



## timbeau (30. Apr 2012)

Wie kommst du darauf. v0 = v2 und beide haben auch a und b drin. 

Erstmal debuggen


----------



## Volvagia (30. Apr 2012)

Wie kommst du darauf? Es wird doch true ausgegeben. true = wahr, false = falsch (im Sinne von "nicht wahr").
Würde v0 und v2 nicht auf die selbe Instanz verweiße würde dir sowieso eine NPE fliegen.


----------



## AquaBall (30. Apr 2012)

Vergleich mal was passiert:

```
v0        ht(A)        v2        ht(C)    [v0]     [v2]
                          ---        -----       ---        -----    ----     ----
v0.add("a");               v0         ???        ???         ???       a       ???
ht.put("A", v0);           v0          v0        ???         ???       a       ???
        
v2 = v0;                   v0          v0         v0         ???       a       a !
v2.add("b");               v0          v0         v0         ???      a,b !   a,b !
        
ht.put("C", v2);           v0          v0         v0          v0       
        
System.out.println(ht.get("A").equals(ht.get("C")));
```

Defakto verwendest du ÜBERALL nur den Verweis auf v0.
Und mit deiner Abfrage fragst du nur ab, auf welche Liste/Listen ht zeigt.
das ist 2 mal dieselbe Liste. dass du an diese SELBE Liste dann auch noch ein "b" dranhängst lenkt nur von den Verweisen auf v0 (==v2!) ab.


----------



## b1zarRe (30. Apr 2012)

Schonmal danke für die Antworten leider raffe ich es immernoch nicht :/ 
Mag es vielleicht wer aufzeichnen oder noch eine andere Idee? Ich verstehe nicht, warum ab v2.add("b") dieses b nicht nur v2 hinzugefügt wird sondern auch v0.

Meine Denke ist eher so: 
v2 = v0; // Arraylist v2 wird vom Inhalt gesetzt wird v0, sprich beide arraylisten haben jeweils ein String "a"
v2.add("b"); // Der Arraylist v2 wird noch ein "b" hinzugefügt... warum auch der arraylist v0 ??? Das checke ich irgendwie nicht.


----------



## timbeau (30. Apr 2012)

Es gibt keine 2 ArrayListen!

v2 = v0 heißt 1 ArrayList!


----------



## Camill (30. Apr 2012)

b1zarRe hat gesagt.:


> v2 = v0; // Arraylist v2 wird vom Inhalt gesetzt wird v0, sprich beide arraylisten haben jeweils ein String "a"



Hier liegt bereits dein Denkfehler, es existiert nur *eine* Liste. Sowohl 'v0' als auch 'v2' "zeigen" auf die selbe Liste.


----------



## Volvagia (30. Apr 2012)

Nein. v0 und v2 sind die selbe ArrayList. Vielleicht ist es physikalisch ja theoretisch möglich, dass sich spontan eine ArrayList um deine Strings bildet, laut dem Ockhamische Prinzip ist es aber weitaus wahrscheinlicher, dass v0 und v2 auf das selbe Objekt verweißen. Oder wie ich sagte: "Ist ja klar, sie kann sich nicht einfach so \"doppeln\"."


----------



## b1zarRe (30. Apr 2012)

Also ich habe es mir jetzt mal aufgemalt:
http://www7.pic-upload.de/30.04.12/j24sjam7ckqg.jpg

Gedankengang:
0. Hashtable ht wird deklariert sowie instanziiert
1. Arraylist v0 wird deklariert sowie instanziiert
2. Arraylist v2 wird deklariert.
3. v0 wird der String "a" hinzugefügt
4. ht wird schlüssel "A" zu v0 "getabled"
5. variable v2 zeigt auf v0 welche hingegen "a" enthält
6. v2 wird "b" hinzugefügt, welches auf v0 zeigt und welches "a" bereits enthält und somit nun "a" und "b"
7. beim vergleich wird dann quasi das abgeprüft:
"a","b".equals("a","b") <- Ich weiß, mistige Syntax... in Worten: es wird egtl. genau das dasselbe geprüft.

Ist das soweit korrekt?

Wenn jemand dazu noch ähnliche Beispiele/übungen/tutorial hat wäre prima... sowas kommt öfter bei uns in den Klausuren vor..


----------



## timbeau (1. Mai 2012)

Jein, lies dir Referenzen durch. Warum hier nochmal alles durchkauen?


----------



## vanny (1. Mai 2012)

die Referenz ist mal ganz plump gesprochen sowas wie ne Telefonnummer.
Egal wer diese nummer wählt hat immer den selben Anschluß am anderen Ende.
v2 = v0 bedeutet quasi v2 bekommt die selbe Telefonnummer unter der er/sie/es seinen passenden Ansprechpartner erreicht. 
*RingRing* .... *knister*...."Hallo Sie sind verbunden mit dem Anschluß der Liste mit a und b..."

Vielleicht hilft dir das ja


----------



## El_Rabbit (1. Mai 2012)

Dekker hat gesagt.:


> Speicheradressen ändern ist in Java nicht möglich. Bist du dir sicher das du das nicht mit c/c++ verwechselst?
> 
> Oder meinst du die Referenzen auf ein Objekt? Dabei handelt es sich allerdings nicht um direkte Speicheradressen sonderen um "Objektadressen" wenn man so will.



Ich möchte deine Aussage nicht anzweifeln, aber ich habe diesbezüglich zufällig ein (nur ein ?) kleines Verständnisproblem.
Vor kurzem habe ich mich durch ein 19 Jahre altes C-Buch "gequält" (eigentlich war das recht nett, aber :roll

Also in C ist es ja so (falls ich das richtig verstanden habe), dass das erste Element eines Vektors (-> Array) sozusagen auf einer (hexadezimalen) Speicher*adresse* im Stack abgebildet wird und dann diese Speicher*adresse* mit jedem nächsten Element von diesem Vektor hexadezimal (in Abhängigkeit von dem Speicherbedarf des entsprechenden Datentyps) "hochgezählt" wird, soweit richtig?

Oder schon falsch?
Ich erinner mich an den Satz im Buch, dass der "Zuwachs" der Speicher*addresse* NICHTS  mit dem Speicherbedarf des Datentyps zu tun hat, kann mich aber an keine Erläuterung erinnern. 
Ich finde das macht keinen Sinn. Wenn ein jedes Element in einem Vektor aus integers z.B. genau 6 Bytes braucht (das stimm nicht, ich weiß), dann kann doch der nächste integerwert in diesem vektor erst entsprechend höher addressiert werden, bzw. ein char mit 1 byte wäre doch viel früher addressierbar???!

Was genau sind denn eigentlich "Referenzen auf ein Objekt" handelt es sich hierbei etwa nicht um die Speicheraddrese vom "Anfang" des Objekts auf dem Heap (Objekte werden ja auf dem Heap gespeichert, stimmt's?) 

Stack und Heap gehören zum RAM, auf dem CPU sind Register oder?

Die zwei oder dreit Bierchen sind bestimmt nicht unschuldig, aber ich habe das Gefühl ich habe die Zusammenhänge noch nicht kapiert wie das alles funktioniert. Mag evtl. jemand 2 bis 2000 Sätze dazu schreiben?  Danke

:rtfm:


----------



## b1zarRe (1. Mai 2012)

Ich dachte ich hätte es verstanden, aber jetzt bringt mich dies hier durcheinander:


```
public static void main(String[] args) {
        String a = "hallo";
        String b;
        b=a;
        b="nicht hallo";
        
        System.out.println("");
        System.out.println(a);
        System.out.println(b);
    }
```

Hier wird ein Stringvariable erzeugt mit "hallo" Wert. Mit 'b=a' müsste doch jetzt die Variable b
auch auf den Wert "hallo" zeigen. Wenn ich b verändere in "nicht hallo" müsste doch b sowie a
"nicht hallo" ausgeben...

Warum kommt bei beiden nun nicht dasselbe heraus?! oO


----------



## Volvagia (1. Mai 2012)

Weil " " einen neuen String erzeugt. Ist wie eine Erzeugung mit "new" mit einen kleinen Unterschied.
Das heißt a zeigt weiterhin auf "hallo", b zeigt auf dem neuen. Würdest du den Inhalt des Strings "hallo" ändern würde es funktionieren. Aber das geht nicht.


----------



## b1zarRe (1. Mai 2012)

Wo meinst du das mit " "?
Ist String b; gleichzusetzen mit String b = " ";
??


----------



## Volvagia (1. Mai 2012)

Nein.


```
b="nicht hallo";
```

Erzeugt einen vollkommen neuen String (sofern bisher keiner mit dem selben Inhalt erzeugt wurde) und lässt b darauf zeigen. Das ändert aber an a nichts.

Ich denke du siehst es falsch. a und b sind keine Strings. Die Rückgabe von "hallo" ist ein String. a und b sind nur Schnittstellen, die auf irgendwelche Strings bzw. ihre Subklassen (die aber in diesen Fall nicht möglich wären) bzw. garnichts (null) zeigen. Die Schnittstellen lassen den String auf dem sie zeigen beliebig ändern. Davon ist weder der String, auf dem vorher bzw. nachher gezeigt wird, bzw. eine andere Variable betroffen.

(Natürlich betrifft das nur Object-Variablen und keine primitiven.)


----------



## b1zarRe (1. Mai 2012)

Mhhh verwirrend... Wie gesagt dachte ich hätte es gecheckt... bislang kann
ich mir nur merken, dass ich bei Objekten wie in dem Beispiel mit der ArrayList auf sowas
achten muss und bei primitiven bzw. Strings sowas nicht passieren kann, ja?

Hat jemand dazu vielleicht noch gute Lesequellen?


----------



## Volvagia (1. Mai 2012)

Bei der ArrayList hast du den Inhalt geändert. Bei den String hast du einen neuen String erzeugt.

Wenn a und b auf das selbe Objekt (ArrayList) verweißen, und du darin etwas änderst zeigt a und b weiterhin auf die selbe Liste. Und dann ist es egal, ob du per a, b, x, q oder uvw zugreifst, solange es auf die selbe Liste zeigt. Nur weil sich in der Instanz eine Variable ändert ändern sich nicht die Variablen, die auf die Instanz zeigen. Sonst hätten wir das pure Chaos. Wenn du eine neue Instanz erzeugst zeigen a und b aber nicht mehr auf das selbe Objekt.


----------



## b1zarRe (1. Mai 2012)

Ist das also bei Strings dann nicht möglich? Und falls nein, warum nicht? String ist ja auch ein Referenz/Klassentyp und kein elementarer Typ wie int oder long zb.

Und besteht dann also kein Unterschied ziwhscnen:

```
String a = "danke fuer die hilfe";
```

und


```
String a = new String("danke fuer die hilfe");
```

?


----------



## Volvagia (1. Mai 2012)

Doch. Ersteres wird im pool gecached bzw. ein bereits existierender String zurückgegeben, bei letzterem immer ein neuer. Das spielt aber bei dem Beispiel keine Rolle, da die Strings nicht den selben Inhalt haben.

Übertragen auf ArrayLists würde dein Beispiel so aussehen:


```
ArrayList<String> a = new ArrayList<String>();
ArrayList<String> b;

a.add("A");
b = new ArrayList<String>();
b.add("B");

System.out.println(a.equals(b));
System.out.println(a.get(0).equals(b.get(0)));
System.out.println(a == b);
```


----------



## Dekker (1. Mai 2012)

El_Rabbit hat gesagt.:


> Also in C ist es ja so (falls ich das richtig verstanden habe), dass das erste Element eines Vektors (-> Array) sozusagen auf einer (hexadezimalen) Speicher*adresse* im Stack abgebildet wird und dann diese Speicher*adresse* mit jedem nächsten Element von diesem Vektor hexadezimal (in Abhängigkeit von dem Speicherbedarf des entsprechenden Datentyps) "hochgezählt" wird, soweit richtig?



Soweit stimmt das schonmal. Alle Datentypen die vor der Laufzeit angelegt werden, werden auf dem Stack platziert, alles was du während der Laufzeit deklarierst (z.b. mit malloc) wird auf dem Heap initialisiert. Der Rest stimmt soweit auch.



> Ich erinner mich an den Satz im Buch, dass der "Zuwachs" der Speicher*addresse* NICHTS  mit dem Speicherbedarf des Datentyps zu tun hat, kann mich aber an keine Erläuterung erinnern.
> Ich finde das macht keinen Sinn. Wenn ein jedes Element in einem Vektor aus integers z.B. genau 6 Bytes braucht (das stimm nicht, ich weiß), dann kann doch der nächste integerwert in diesem vektor erst entsprechend höher addressiert werden, bzw. ein char mit 1 byte wäre doch viel früher addressierbar???!



Das liegt glaube ich daran das dein Buch so uralt ist. Es kommt hier auf den Compiler an. Es gab früher Compiler die immer in einer bestimmten größe Platz angelegt haben. Allerdings gehen Compiler so vor wie du es dir vorstellst. 

Was genau sind denn eigentlich "Referenzen auf ein Objekt" handelt es sich hierbei etwa nicht um die Speicheraddrese vom "Anfang" des Objekts auf dem Heap (Objekte werden ja auf dem Heap gespeichert, stimmt's?) 



> Stack und Heap gehören zum RAM, auf dem CPU sind Register oder?



So in etwa, ja.


----------



## cmrudolph (1. Mai 2012)

Dekker hat gesagt.:


> Das liegt glaube ich daran das dein Buch so uralt ist. Es kommt hier auf den Compiler an. Es gab früher Compiler die immer in einer bestimmten größe Platz angelegt haben. Allerdings gehen Compiler so vor wie du es dir vorstellst.



Auch heutige Compiler gehen noch so vor, dass sie mehr Speicher allozieren als sie eigentlich benötigen, um die Zugriffsgeschwindigkeit zu erhöhen. Der Speicher wird in Blöcke eingeteilt. Wenn man auf diese Compileroptimierung verzichten möchte (weil man z.B. ein riesiges Array mit einzelnen Bytes hat und nicht 4x soviel Speicher verbrauchen möchte), dann ist die Zugriffsgeschwindigkeit langsamer aber man vergeudet keinen Speicher.

Und komplett unabhängig vom Datentyp kann die Speicherbelegung gar nicht sein. Ein Struct bestehend aus zwei Integern braucht z.B. mehr Speicher als nur ein Integer.

Was vielleicht auch noch interessant ist: man kann den reservierten Speicher nicht einfach so vergrößern. Wenn man also Speicher für ein Array mit 1000 Elementen reserviert hat und dann doch 1500 Elemente benötigt, dann kann man den reservierten Speicher nur dann vergrößern, wenn der Speicherbereich hinter dem Array zufällig noch frei ist. Ansonsten muss man sich an anderer Stelle im Speicher den Platz für 1500 Elemente suchen und die Daten dorthin kopieren.


----------



## AquaBall (1. Mai 2012)

Wir haben bei jeder Variable grundsätzlich mit 3(!) Werten zu tun (wohl in den meisten Sprachen) :
die Variable a =  der SpeicherPlatz wo die Variable selbst steht.  Kannst du in Java nicht manipulieren
der Inhalt von a = die Adresse/der Verweis auf das object 
der Inhalt des Objectes = der eigentliche "Wert" der Daten

In C/C++ kannst du über "^pointer" auch auf die erste Ebene zugreifen, was C so mächtig, aber auch so gefährlich und empfindlich macht. In Java fehlt diese Ebene.


Vielleichst verstehst du jetzt besser:

a="hallo"
b=a
b="Nicht hallo"  // heißt: zeige mit b auf einen neuen String
// (heißt nicht: fülle das, wo b hinzeigt, neu )
// also bleibt a unberührt.
==>  a!=b


a=object
b=a
b.fill(object2)  // heißt: fülle das, wo b hinzeigt, mit neum Inhalt
// der Zeiger in b und a ist gleich
// dadurch wird auch das wo a hinzeigt verändert!
==> a==b


a=object
b=a
b=object2   // heißt: zeige mit b auf einen neues Object
// also bleibt a unberührt.
==> a!=b


----------



## b1zarRe (2. Mai 2012)

Um nicht extra einen neuen thread aufzumachen: warum sind Strings "konstant" prinzipipiell kann ich doch in einen bereits erstelleten string diesen mit einer neuen zeichenkette belegen.... Pder wird dann intern ein neuer string auf dem heap angelegt??


----------



## Volvagia (2. Mai 2012)

Wie willst du das machen?


----------



## b1zarRe (2. Mai 2012)

Das meine ich..:


```
String test = "blabla";
test = "was anderes"; // bei sout(test) wuerde ja nun was anderes herauskommen
```


----------



## Volvagia (2. Mai 2012)

Wie soll - sofern alles schön private ist - "=" etwas IN einer Instanz ändern? Das geht nur über Methoden btw. internen Vorgängen.


----------



## vanny (2. Mai 2012)

Strings sind in Java halt gesondert zu betrachten, da sie in einem Pool landen.
Sie können mit 
	
	
	
	





```
String string = "bäm"
```
 direkt erzeugt werden ohne new - Operator.
Sollte bäm jetzt schon im Pool liegen, erzeugst du keinen neuen Eintrag, sondern verlinkst die Referenz(wobei ich für diese Beizeichnung keine Haftung übernehme).
Auch
	
	
	
	





```
String a = "Hallo";
String b = "Welt";
String c = a + " liebe " + b;
```
erzeugt mehr Strings als man eigentlich denk, da wäre "Hallo liebe" und dann erst "Hallo liebe Welt".
Um damit besser umgehen zu können, gibt es den StringBuilder.
Dieser wird mittlerweile auch implizit von Java genutzt, wenn man wie im unteren Beispiel arbeitet.
Es gäbe noch viel mehr zu sagen aber merk dir einfach, STRINGS SIND IMUTABLE also UNVERÄNDERLICH!

Gruß Vanny


----------



## b1zarRe (2. Mai 2012)

Und der Unterschied zwischen


```
String a = "hallo";
String b = "hallo";
String c = new String("hallo");
```

Wäre dann, dass man einen neuen String mit dem Wert "hallo" im Pool hat,
String b verweist auf den selbigen und String c erzeugt einen neuen String auch mit
dem Wert "hallo".. Also wären dann insgesamt 2x "hallo" im Pool, korrekt?

Ich meinte den Code von oben, dass dieser in der main Methode aufkommt, also:


```
public static void main(String[] args) {
  String a = "hallo";
  a = "nicht hallo";
}
```

Würde das nun bedeuten, dass im Pool "hallo" sowie "nicht hallo" liegt ODER 
das nurnoch "nicht hallo" darin liegt? Weil demzufolge wäre doch dann die
Variable(!)a vom Typ String veränderlich, oder?

Ich weiß das klingt sehr danach als ob ich in Java 2 Wochen gerade etwas mache(was nicht so ist ),
aber möchte das gerne genau und korrekt verstehen, da bei uns ab und an "fiese" Klausuren
kommen, wo genau solche "KLeinigkeiten" abgefragt werden.

Andere Frage: Ich habe leider immernoch nicht in meinem Programmierdasein verstanden,
warum die main Methode als Parameter String[] args hat??? Die main Methode wird ja
als erstes aufgerufen, und veranlasst alle weiteren Methoden zu starten. Soweit so klar... Aber müsste dann
nicht sinnigerweise der Parameter Object[] args sein? Oder was genau bzw, wofür genau ist dieser
Parameter... was wird da übergeben? Irgendetwas von Java 'festgesetztes' oder wie kann man das verstehen?


----------



## Volvagia (2. Mai 2012)

Nein, 2x idente Strings im Pool bringt nichts.
a und b müssten auf den selben String zeigen, c auf einen gleichen.

Beides sollte darin liegen.

Die Variable a ist nicht unveränderbar, da sie zuerst auf "hallo" und dann auf "nicht hallo" zeigen würde. Variablen haben nichts mit dem Pool zutun, der liegt grundsätzlich außerhalb deiner Zuständigkeit.

Da die Start-(Programm)-Parameter eines Programms nun mal Zeichenfolgen sind.

Nach 2 Wochen Java hat man (meiner Erfahrung nach) das ganze bereits verstanden und als Tatsachen abgehakt.


----------



## AquaBall (2. Mai 2012)

b1zarRe hat gesagt.:


> Das meine ich..:
> 
> 
> ```
> ...



"was anderes" muss auf jedenfall vom Compiler erzeugt werden. Sonst könntest du im Code gar nicht tippen.
Und nun hat Java halt beschlossen, dass 
	
	
	
	





```
test = "was anderes"
```
 eben nicht heißt 
	
	
	
	





```
"fülle den von 'test' angezeigten Speicher neu"
```
, sondern 
	
	
	
	





```
"'test' soll auf den neuen (eh schon erzeugten) String zeigen"
```
;  geht schneller und ist platzsparender.

Was du eigentlich meinst (oder erwartest), liese sich mit "
	
	
	
	





```
test.neuFüllen("was anderes")
```
" evtl. realisieren. Aber das gibt's halt (standardmäßig) nicht und würde Probleme bringen, wenn die Strings unterschiedlich lang sind, ...
Ist halt ein Unterschied zw. C und Java.

[TIPP]PS: Obwohl es schon oft durchgekaut wurde, hier nochmal:
Das ist auch der Grund warum

```
String a="text";
String b="text";
if (a==b)
```
im allgemeinen FALSE ergibt.
Weil a und b zwar auf Strings verweisen, die sich gleichen, aber dennoch 2 x erzeugt wurden. (Hast du ja im Sourcecode 2 x getippt!) Somit sind 2 Zeichenketten entstanden, die an unterschiedlichen Stellen stehen (müssen).
[WR]Deshalb musst du Strings unbedingt vergleichen mit:

```
if (a.equals(b))
```
 das ergibt TRUE.[/WR]
(Und zur gänzlichen Verwirrung: Der Compiler ist meistens intelligent genug, die Gleichheit von 2x "text" und "text" zu erkennen, und macht dann üblicherwiese nur 1x "text"; also ergibt "a==b" dann unter Umständen doch TRUE, aber das ist eher ein falscher Fehler, und du kannst dich nicht drauf verlassen!
[/TIPP]


----------



## b1zarRe (2. Mai 2012)

Jau, also den Unterschied zwischen Equals/== habe ich geschnallt. 
== Identität->"dasseble", equals(bei eigenen Klassen überschreiben) ->"das gleiche"

Zu String[] args: Kann ich darunter verstehen, das wenn ich ein Java Programm per Kommandozeile
starte mit: java eineTestklasse.class man hinter dem "class" noch weitere Parameter eingeben könnte, welche
in diesem String Array "String[] args" mitübergeben werden, oder wie?

Und ich glaube das mit
String a = "hallo";
a = "nicht hallo";

habe ich nun begriffen: Variable vom Typ String wird deklariert und instanziiert und zeigt auf den Wert "hallo", welcher
im Pool irgendwo rummschwimmt.() In der nächste Zeile wird NICHT genau dieser wert überschrieben, SONDERN
"Nicht hallo" im Pool abgelegt und nun zeigt a nichtmehr auf "hallo" sondern auf "Nicht hallo". Und deshalb sind Strings konstant, da
"hallo" noch irgendwo im Pool ist, korrekt? Und bleibt "hallo" da für immer oder wird das mit dem Garbage Collector nach einiger Zeit gelöscht?


----------



## Volvagia (2. Mai 2012)

Ja. Es lassen sich der VM und dem Programm Argumente übergeben. Der VM kann man z. B. den maximal assoziierbaren Speicher mitgeben, dem Programm eine Pfad zu einer Sprachdatei oder was auch immer.

Und nein: Die Variable wird nicht instanziert. Der String wird instanzier. Die Variable zeigt auf einen anderen String, da du einen neuen String intialisierst und ihr sagst: "Zeige auf dem String". Das ist alles.

Strings sind nicht immuntable da sie im Pool rumschwimmen (klingt irgendwie eklig), sondern da es keine setter für das interne Char-Array gibt. Du kannst theoretisch jede eigene Klasse immuntable machen, du darfst einfach keine Setter für die Klassenvariablen einsetzen. (Oder du finalisierst die Variablen einfach.) Ersteres solltest du dir merken, da jede Methode die etwas mit dem String macht (substring z. B.) immer einen neuen String zurückgibt. Deshalb bringen solche Konstrukte recht wenig:


```
public void some() {
	String s = "Hallo";
	s.substring(2);
	System.out.println(s);
}
```

Ich gebe keine Garantie dafür, aber was ich gehört habe werden die Strings-Intialisierungen bereits zur Compilerzeit erkannt und müssten deshalb bis zum Programmende gecached bleiben.


btw. in der Standartimplementation von equal in Object macht equal genau das Selbe wie "==":


```
return(this == obj);
```


----------

