2013-04-13 20 views
5
 String s1 = new String("string"); 
     String s2 = new String("string"); 

     String s3 = "string"; 
     String s4 = "string"; 

     System.out.println(s1 == s2);  //FALSE 
     System.out.println(s2.equals(s1)); //TRUE 

     System.out.println(s3 == s4);  //TRUE 
     System.out.println(s3.equals(s4)); //TRUE 

Qual è la differenza tra la creazione di s1 e s3? Per favore fatemi sapereAssegna e creare nuova differenza String

In String stiamo avendo solo oggetto String quindi perché tratta questi due in modo diverso. s1 e s2 hanno un indirizzo di memoria diverso mentre s3 e s4 hanno lo stesso indirizzo di memoria. perché funziona in base all'operatore new.?

+0

Se si desidera rendere chiari i concetti in stringa java, leggere KathySierra Scjp 6. Il capitolo 6, Stringa, ha una spiegazione meravigliosa sui mezzi a corda, nessuno è in grado di spiegare meglio di lei. Se vuoi che il pdf ti dia un email ID a [email protected] Se qualcun altro è interessato, possono anche mandarmi una mail. –

+0

Grazie appena ottenuto ..... – sunleo

risposta

5

Gli oggetti String che rappresentano stringhe letterali nel codice sorgente Java vengono aggiunti a un pool condiviso String quando vengono caricate le classi che li definiscono. Ciò garantisce che tutte le "copie" di un letterale String siano effettivamente lo stesso oggetto ... anche se il letterale appare in più classi. Questo è il motivo per cui s3 == s4 è true.

Al contrario, quando si imposta new una stringa, viene creato un nuovo oggetto String distinto. Questo è il motivo per cui s1 == s2 è false. (Questa è una proprietà fondamentale di new. È garantito per creare e restituire un nuovo oggetto ... se si completa normalmente.)

Tuttavia, in entrambi i casi, le stringhe avranno gli stessi caratteri, ed è per questo che equals restituisce true.


Mentre è importante capire che cosa sta succedendo, la lezione vera è che il corretta modo per confrontare le stringhe Java è quello di utilizzare equals e non ==.

Se si desidera disporre che gli oggetti String possano essere testati per l'uguaglianza utilizzando ==, è possibile "internalizzarli" utilizzando il metodo String.intern. Tuttavia, devi farlo costantemente ... e l'interning è un processo costoso sotto vari aspetti ... quindi generalmente non è una buona idea.

+0

perché internare è un processo costoso? – AmitG

+1

Un numero di fattori. 1) C'è una tabella hash che utilizza la memoria e viene rilevata/aggiornata quando si chiama 'intern'. 2) Ogni stringa internata deve essere memorizzata nella tabella hash usando un riferimento debole. Questa è memoria extra + sovraccarico di GC. 3) Le stringhe internate sono memorizzate nello spazio "permgen" (generalmente limitato). GC'ing permgen di solito comporta un GC completo. –

+0

grande spiegazione. Ho letto da qualche parte, le stringhe Java 1.7 non vanno nell'area di heap di PermGen? è vero? – AmitG

2

La JVM ha un'ottimizzazione automatica. A meno che non si crei appositamente un nuovo oggetto String e un altro oggetto String esista già con lo stesso valore, lo JVM assume automaticamente che un nuovo oggetto non è necessario e assegnerà un puntatore allo stesso oggetto String già esistente.

In sostanza, quando si utilizza la seconda opzione, questo è ciò che accade:

Fase 1

primo oggetto viene creato nessun problema.

Fase 2

Prima si crea il secondo oggetto, la piscina String viene controllato per un valore. Se quel valore esiste attualmente, non è necessario creare un nuovo oggetto. Restituisce solo il riferimento all'oggetto String.

Fase 3

Invece di essere assegnato un nuovo oggetto, esso è semplicemente dato un riferimento all'oggetto fatta allo step 1. Questo è per risparmiare memoria.

+1

Perché il downvote? – christopher

3

s1 è un nuovo oggetto String che non appartiene a una parte di qualsiasi istanza raggruppata. s3 è un'istanza di una stringa proveniente da un pool. Ricerca java Pool di stringhe. Dai uno sguardo al relativo metodo intern() su String.

Il concetto non è esclusivo di java. String interning è supportato in altre lingue. Su tale nota correlata, il raggruppamento di oggetti di uso frequente segue lo schema flyweight e non è limitato alle stringhe. Dai uno sguardo allo Integer.valueOf(). Anche gli integer hanno un pool costante.

0

Questo accade perché l'operatore new forza la creazione di una nuova istanza di String, mentre nel secondo caso, poiché String è una classe immutabile, la JVM fornisce la stessa istanza di Stringa per entrambe le variabili per il salvataggio della memoria. Poiché non vi è alcuna possibilità che uno di questi oggetti cambierà causando anche il secondo cambiamento (immutabile, ricordi?) Questo è OK.

Problemi correlati