Referenz vs. Objekt



  • Hi,

    Ich hab ein Verständnisproblem: Ich habe zwei Möglichkeiten ein String-Objekt zu erstellen:
    1.:

    String string1 = "Java";
    String string2 = "Java";
    if(string1 == string2)...
    

    --> if ergibt eine wahre Aussage.

    Aber 2.:

    String string1 = new String("Java");
    String string2 = "Java";
    if(string1 == string2)...
    

    --> if ergibt eine falsche Aussage

    Wieso gibt es hier unterschiedliche Verhalten?

    lg



  • Strings musst du in Java mit equals vergleichen.



  • Ja ich weiß, aber es wundert mich trotzdem dass die 1'te Möglichkeit funktioniert.


  • Mod

    Im ersten Fall steht der Inhalt des Strings beim Start des Programms fest. Alle Strings, die so angegeben sind, werden also beim Start angelegt. Und dann wird auch geguckt, ob ein String mit einem gegebenen Inhalt schon existiert. Wenn das der Fall ist, wird kein neuer String angelegt, sondern einfach eine Referenz auf den alten gesetzt. Das kann Java so machen, da Strings "immutable" sind. Wenn Du aber explizit "new String("jkbasjkb");" sagst, gibst Du Java keine andere Wahl, als ein neues String-Objekt zu erzeugen. Genau das macht new eben.

    Du könntest mal ausprobieren, was mit String s = String.valueOf("Java"); passiert. Dort gibst Du Java nämlich die Möglichkeit, kein neues Objekt zu erstellen.

    Generell ist das ganze Verhalten in dem Zusammenhang aber AFAIK nicht garantiert. Du solltest also nicht damit rechnen, auf diese Weise an Vergleichen mit equals herumzukommen. Dann funktioniert Dein Programm plötzlich nicht auf allen JVMs.

    Es ist halt eine Optimierung, um Speicherplatz zu sparen.



  • Seit Java 7 kann man Strings doch auch mit == vergleichen?



  • tzi schrieb:

    Seit Java 7 kann man Strings doch auch mit == vergleichen?

    Man konnte es schon immer, und das Verhalten ist seit jeher gleich. Nur ist es nicht so, wie es das ungeübte Auge erwarten würde. Um nochmals das Beispiel anzuführen:

    public final class j7StringCompare {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            String first = new String("Java"),
                   second = "Java";
    
            if (first == second) {
                System.out.println("equal");
            } else {
                System.out.println("not equal");
            }
        }
    
    }
    

    ➡ "not equal"

    Was hingegen geht, ist ein switch -Statement mit Strings als Sprungmarken anstelle von int s. Wofür das gut sein soll, ist mir ein Rätsel.



  • Gregor schrieb:

    Es ist halt eine Optimierung, um Speicherplatz zu sparen.

    Naja aber auf kosten der Performance. Oder meintest du vielleicht dass diese Optimierung nur beim kompilieren durchgeführt wird?


  • Mod

    Patrickssj6 schrieb:

    Gregor schrieb:

    Es ist halt eine Optimierung, um Speicherplatz zu sparen.

    Naja aber auf kosten der Performance. Oder meintest du vielleicht dass diese Optimierung nur beim kompilieren durchgeführt wird?

    Ich denke nicht, dass das sehr auf die Performance geht. Du berechnest halt, wenn ein String benötigt wird, seine Hashsumme und vergleichst ihn dann mit möglicherweise gleichen Strings. Dadurch kann die Erzeugung geringfügig länger dauern. ...aber das kann man ja auch verhindern, indem man explizit "new" nutzt. Ansonsten sollte es eher positiv für die Performence sein, wenn weniger Speicher verbraucht wird.


Anmelden zum Antworten