2009-12-13 1 views
5
public class A { 

    static String s1 = "I am A"; 

    public static void main(String[] args) { 
     String s2 = "I am A"; 
     System.out.println(s1 == s2); 
    } 
} 

Sopra le uscite del programma "true". Entrambi sono due identificatori/oggetti diversi su come l'output è "vero"?Domanda Java di base: parità di stringhe

La mia comprensione è che la JVM creerà riferimenti diversi per ciascun oggetto, in tal caso come è vero l'output?

risposta

20

Java gestisce un pool letterale String. Riutilizza questi letterali quando può. Pertanto i due oggetti sono in realtà lo stesso oggetto String e restituisce true ==.

Credo che questo si chiama string interning

+1

Per informazioni sul pool di stringhe, dai un'occhiata a wikipedia: http://en.wikipedia.org/wiki/String_interning (+1 stessa idea) –

+1

Sì, i letterali stringa sono automaticamente internati, come da metodo interno API - http : //java.sun.com/javase/6/docs/api/java/lang/String.html – Ash

+1

Non sono solo i letterali internati, ma anche le costanti di compilazione. –

1

Non si sta confrontando il contenuto delle stringhe. Stai solo confrontando i riferimenti dell'oggetto. È necessario utilizzare il metodo uguale (che è un membro della classe String). In alternativa, oppure è possibile utilizzare il metodo compareTo (anche nella stessa classe String) per verificare se il valore restituito è zero.

Si prega di notare che il testo sopra era più di un forte suggerimento allo stato originale della domanda in quanto sembrava che l'OP fosse inconsapevole del processo attuale che si svolge dietro le quinte.

Gli altri ragazzi che suggerivano internalling avevano ragione. Per rispondere a questa domanda non ho avuto abbastanza tempo per andare al libro di Java Puzzlers. Sospettavo qualcosa riguardo l'impostazione dello stesso riferimento in fase di compilazione, ma non sapevo come trovare un riferimento anche a questo.

+0

Se confronto il contenuto, allora la risposta è decisamente 'vera' Ma qui entrambi sono due variabili diverse, ha vinto 't jvm crea due riferimenti diversi? – novice

+1

@Felix. No, lui sta confrontando i riferimenti e l'output è vero - che è esattamente il risultato leggermente sorprendente che ha provocato questa domanda –

+2

Perché hai ragazzi? redatto una risposta corretta? –

5

Perché il Java Language Specification dice: letterali, o

String, più in generale, stringhe che sono i valori di espressioni costanti (§15.28) -sono "internato" in modo da condividere istanze uniche , utilizzando il metodo String.intern.

6

== verifica che le variabili puntino esattamente alla stessa istanza di un oggetto. I due valori letterali di stringa che hai creato puntano allo stesso punto in memoria e quindi sono uguali. I valori letterali stringa sono internati in modo che la stessa stringa letterale sia lo stesso oggetto in memoria.

Se si dovesse fare

String s = new String("foo"); 
String t = new String("foo"); 

Poi == sarebbe return false e s.equals (t) sarebbe restituire true.

5

E 'per un'ottimizzazione memoria eseguita dal compilatore ... cioè, String costanti (cioè - String s ottenuti con gli stessi String letterale) utilizzano lo stesso String oggetto dal Strings sono immutabili. L'operatore == controlla solo che due oggetti siano lo stesso oggetto reale.

Se riesci ad afferrare il libro Java Puzzlers di Joshua Bloch e Neal Gafter, e guarda il puzzle 13, "Animal Farm" ... ha ottimi consigli su questo argomento. Ho intenzione di copiare un testo rilevante:

"Si può essere consapevoli che le costanti in fase di compilazione di tipo String sono internati [JLS 15.28] In altre parole ogni due espressioni costanti di tipo String che designano la stessa sequenza di caratteri sono. rappresentato da riferimenti di oggetti identici ...Il tuo codice dovrebbe raramente, se mai, dipendere dall'internamento delle costanti di stringa. Interning è stato progettato esclusivamente per ridurre l'ingombro della memoria della macchina virtuale, non come strumento per i programmatori ... Quando si confrontano i riferimenti agli oggetti, è preferibile utilizzare il metodo equals per l'operatore == a meno che non sia necessario confrontare l'identità dell'oggetto piuttosto che il valore .".

Questo è dal riferimento di cui sopra ho accennato ... pagine 30 -. 31 nel mio libro

+1

Ho menzionato questo [concesso non ho menzionato il motivo per cui lo ha fatto], e ho votato per questo. – monksy

+0

+1 Per aver menzionato i Puzzlers e una spiegazione del perché – monksy