2013-07-23 5 views
5

Sto cercando di capire la classe String di Java ma sto riscontrando difficoltà a comprendere la situazione descritta di seguito.Utilizzo di intern in stringhe java

Si consideri il seguente frammento di esempio:

String x = new String("Hey"); 
String y = "Hey"; 

Se uso bool = y == x.intern(); la variabile bool sarà pari true.

La mia domanda è:

Quando faccio una dichiarazione come questa:

String b = "h"; 
String a = b.intern + "ey"; 
boolean x = a == "hey"; 

x 's valore sarebbe false ma quando faccio a = (b + "ey").intern();x' valore s sarò true .

Perché il x = true non è nel secondo esempio? È perché le dichiarazioni nel primo esempio non sono uguali? Se sì, quali sono le differenze?

+0

Il seguente collegamento potrebbe essere utile: https://weblogs.java.net/blog/2006/06/26/all-about-intern –

+1

'String + String' restituisce una nuova stringa che * non * magicamente internato: non tenta di trovare stringhe internamente esistenti con lo stesso contenuto. Ora, se entrambe le espressioni String sono letterali, l'intera espressione potrebbe essere * piegata * durante la compilazione, il che significa che solo il risultato * viene trovato nell'output compilato ed è soggetto a regole interne standard, ma questo porta a un caso carino diverso: '(" h "+" ey ") ==" hey "' è vero. Non appena la piegatura è * eliminata * (cioè con una variabile) questo scompare. – user2246674

+0

@TariqAyman Ho apportato alcune modifiche alla tua domanda, cercando di migliorare la sua formattazione. Si prega di rivedere se si ritiene che qualsiasi punto della tua domanda è stato perso. – acdcjunior

risposta

5

Con il primo esempio:

String y = "Hey"; 

Java Stagisti automaticamente stringhe come questa (JLS section 3.10.5):

Inoltre, una stringa letterale si riferisce sempre alla stessa istanza di classe String. Questo perché stringhe letterali - o, più in generale, stringhe che sono i valori delle espressioni costanti (§15.28) - sono "internate" in modo da condividere istanze univoche, utilizzando il metodo String.intern.

Così, quando si chiama x.intern(), si ottiene la copia internati di "Hey", quindi sono lo stesso oggetto e == rendimenti true.

Ma nel secondo esempio, b.intern() è una chiamata di metodo che viene valutata in fase di esecuzione, e operatore di concatenazione di Java restituirà un nuovo String (non internati), che è un oggetto diverso dalla stringa letterale "hey" (già internati), quindi == restituisce false (oggetti diversi).

EDIT

Per chiarire cosa succede con la concatenazione di stringhe, girare a JLS Section 15.18.1:

Il risultato della concatenazione di stringhe è un riferimento ad un oggetto String che è la concatenazione della due stringhe di operando. I caratteri dell'operando di sinistra precedono i caratteri dell'operando di destra nella stringa appena creata.

L'oggetto String è stato appena creato (§12.5) a meno che l'espressione non sia un'espressione della costante di compilazione (§15.28).

Ma, b.intern() + "ey"; è non una fase di compilazione espressione costante, quindi l'oggetto String risultante non è stato internati, e == rileverà che è un oggetto diverso dal internati "hey".

+0

Grazie per averlo eliminato ma se si crea una nuova stringa come b = "h" + "ey" questa è una stringa concatenata ma sarà uguale a "hey" perché non ci sono oggetti ? –

+0

Il compilatore ottimizza il '+' e inserisce automaticamente il risultato. –

+1

@LeeMeador Questo vale per un'espressione costante in fase di compilazione come '" h "+" ey "', ma non per qualcosa che riguarda una chiamata al metodo, come 'b.intern() +" ey "'. – rgettman

3

Questo crea una stringa e lo memorizza:

String a = b.intern() + "ey"; 

Questo crea una stringa, stagisti IT e memorizza la versione internati:

String a = (b + "ey").intern(); 

Tutte le stringhe internati con lo stesso contenuto sono ==

Tutti i valori letterali di stringa (stringhe fornite nella forma "hey") sono internati dal compilatore internamente.

stringhe che non sono internati, ma hanno lo stesso contenuto sono solo equal() e non ==

Ai posteri, un altro ... in cui il compilatore ottimizza la + con conseguente "hey" e stagisti che così come sarebbe la stringa letterale "hey"

String a = "h" + "ey"; 
+0

grazie, ma allora perché String b = "h" + "ey" equivale a "hey" non è lo stesso di b .intern() + "ey"? –

+0

Né è internato, quindi non sono '=='. Saranno 'uguali()'. Lo stesso contenuto. Posizione diversa in memoria. –

+1

@Lee Meador - 'intern()' è un metodo * * –

0

Java concatena String s utilizzando una StringBuilder:

b.intern() + "ey" si trasforma in qualcosa di simile a
new StringBuilder(b.intern()).append("ey").toString(). Questo crea un nuovo String, quindi non sarà == a "hey".