2011-09-20 22 views
9

Diciamo che sono tre corde,Confronto tra due stringhe con "==": quando funzionerà?

String s1 = "string one"; 
String s2 = new String("string one"); 
String s3 = "string one"; 

so che è vero che è s1 == s2false, ma ho letto da qualche parte che è s1 == s3true. È corretto? Perché o perché no?

+2

Se sia o non sia di interesse passeggero, ma non dovresti farlo.'==' è per _object identity, _ not string confronti. – paxdiablo

+0

@paxdiablo: se gestisci esclusivamente stringhe letterali, è ok usare '=='. Ma dover documentare che in genere è un tale dolore è più facile usare semplicemente 'equals()' su tutta la linea. –

+1

sì, lo so tutto questo. ho programmato in Java per anni e mi stavo chiedendo :). non sembra che dovrebbe essere così ... –

risposta

21

I valori letterali delle stringhe sono internati automaticamente. Quindi s1 == s3 è vero. Le stringhe possono essere create nel pool costante di stringhe oppure possono essere create nello spazio heap. Se intern una stringa creata nell'heap, la stringa si troverà nel pool costante di stringhe.

Quando si crea una stringa letterale (String s1 = "string one"), la stringa viene creata nel pool di costanti di stringa. Inoltre, il pool di costanti di stringhe non memorizza i duplicati. Quindi, quando si dice,

String s1 = "string one"; 
String s3 = "string one"; 

Sia S1 e S3 punterà alla stessa istanza della stringa nella stringa piscina costante. Quindi s1.equals (s3) sarà vero. E s1 == s3 è anche vero; poiché entrambi i puntatori sono uguali.

Tuttavia, quando si crea un'istanza di una stringa utilizzando la "nuova" costruttore

String s2 = new String("string one"); 

poi s2 si crea nello spazio di heap. Lo spazio heap è un'area di memoria diversa rispetto al pool costante di stringhe

Quindi mentre s1.equals (s2) è vero, s1 == s2 è falso; dato che indicheranno diverse aree di memoria.

Tuttavia, è possibile convertire una stringa creata utilizzando il "nuovo" costruttore per spostarlo nel pool costante di stringhe richiamando la funzione intern(). Quindi s2.intern() restituirà una stringa nel pool costante di stringhe; sebbene s2 sia stato originariamente creato nell'heap.

+0

Credo che questo sia vero solo all'interno di un'unità di compilazione? Cioè, non credo che il più generale: 'A.x == B.x' è necessariamente vero. –

+2

-1 per la prima frase ingannevole, priva di significato e senza menzione dell'internamento delle stringhe. –

+0

@pst: lo interning delle stringhe funziona su tutte le classi. –

4

Sì, è vero, perché i valori letterali stringa sono tutti internati. Leggi la documentazione per String.intern() per maggiori dettagli.

Di conseguenza, questi sono tutti uguali oggetto (e si confronta con uguale ==):

s1 
s3 
s1.intern() 
s2.intern() 
s3.intern() 
1

sopra è COME.

e dovresti sapere perché.

A) stringa varaible dichiarata in tempo ref compilazione di costante nel raggruppamento costante

B) stringa risultato varaible dal metodo ref per oggetto nello spazio mucchio.

tutto a causa della specificazione di JVM e del suo design di memoria.

A) è perché le stringhe sono immutable.when classe java compilazione e classe di carico JVM, JVM trovato una variabile String dichiarata dal vostro in tempo di codifica. Causa è costante, JVM mettere la costante a "Constant Pool Runtime" area di memoria . e, costante è unico.

B) è verysimple. poiché la variabile di runtime di jvm utilizza lo spazio heap.

Problemi correlati