2014-11-30 12 views
14

Quindi, mi rendo conto che le domande che sto per porre riguardano un argomento che è stato battuto fino alla morte più e più volte, tuttavia, anche dopo aver letto tutte le risposte e la documentazione che ho trovato, sono ancora un po ' confuso sull'internamento delle stringhe. Forse è dovuto alla mia mancanza di comprensione per la JVM; forse è dovuto alle modifiche introdotte in Java 7 che svalutano molte delle risposte e della documentazione sopra menzionate. Ad ogni modo, mi sono bloccato, e spero che qualcuno possa aiutarmi a capire il concetto un po 'più chiaramente ...Come funziona lo interning delle stringhe in Java 7+?

String a = "text"; 
String b = new String("text"); 

Nell'esempio di cui sopra, capisco che verranno creati due oggetti String. Capisco anche che ci sarà un solo array char contenente la sequenza 't', 'e', ​​'x' e 't' in memoria. Tuttavia, dove sono in memoria ciascuno degli oggetti stringa effettivamente memorizzati? Se quello che ho letto ho letto correttamente: il riferimento della variabile a verrà memorizzato nel pool costante mentre il referente di b verrà memorizzato nell'heap, giusto? In tal caso, sono confuso su come il pool interno mantiene stringhe internate. Tiene traccia delle stringhe definite nel pool costante e quelle che sono state internalizzate manualmente (invocato .intern()) dall'heap? JVM crea gli oggetti stringa definiti nel pool costante e li carica nel pool interno? Sono confuso su come tutto funziona ...

Ancora, scusa per aver posto domande così confuse/asinine, è solo che sono relativamente nuovo alla struttura e ai meccanismi interni dello JVM e un sacco di mi ha lasciato girare la testa. Grazie!

+2

ti suggerisco leggi tutte le risposte [qui] (http://stackoverflow.com/questions/27123131/underlying-mechanism-of-string-pooling-in-java) –

+1

Nulla di fondamentale è cambiato per quanto riguarda lo interning delle stringhe in Java 7 e 8 rispetto alle versioni precedenti. – Jesper

risposta

7

C'è una cosa che si chiama String Memory Pool in Java, quando si dichiara:

String str1="abc"; 

Si va a quel pool di memoria e non sul mucchio. Ma quando si scrive:

String str2=new String("abc"); 

Si crea un oggetto pieno titolo sul mucchio, se ancora una volta scrive:

String str3 = "abc"; 

non creerà più oggetto sulla piscina, si verificherà la se questo letterale esiste già, lo assegnerà ad esso.Ma la scrittura:

String str4 = new String("abc"); 

sarà di nuovo creare un nuovo oggetto sul mucchio

punto chiave è che:

Un nuovo oggetto viene sempre creato sul mucchio tutte le volte che si mantiene scrivendo:

new String("abc"); 

Ma se si mantiene l'assegnazione delle corde direttamente senza utilizzare la parola chiave nuova, sarà solo ottenere riferimento dal pool di memoria (o ottenere creato se non presente nella memoria di poo l)

Il metodo intern() trova se la stringa è presente nel pool di memoria se non lo aggiunge al pool di memoria e restituisce un riferimento ad esso. quindi, dopo aver usato questo metodo, il riferimento alla stringa del tuo non punta a nessun oggetto sull'heap, punta a un oggetto nel pool di memoria stringa (Inoltre, nota che il pool di memoria contiene solo stringhe univoche)

+2

A partire da jdk 7 e 8, gli oggetti String internati vengono anche memorizzati nell'heap. http://java-performance.info/string-intern-in-java-6-7-8/ – nanosoft

+0

Che dire della nuova stringa ("test"). intern() posiziona l'oggetto se non è già esistente? E se 1. il letterale è già in pool, o 2. è già in heap? – xploreraj

+0

@xploreraj controlla i documenti java api per intern(), lo scopo è chiaramente specificato. –

5

Quando si dice new String() si ottiene un nuovo riferimento in modo da considerare Object

String a = "text"; 
String b = new String("text"); 
System.out.println(a == b); 
b = b.intern(); 
System.out.println(a == b); 

Poi prima a == b visualizzerà false perché sono diversi riferimenti. Se abbiamo b dicendo b = b.intern() possiamo quindi testare nuovamente e ottenere true. Spero che aiuti. Il codice sopra ha funzionato allo stesso modo in Java dalla versione 1.0 (e funziona ancora oggi in Java 8).

+0

Grazie per la rapida risposta, Elliott. Capisco che entrambe le condizioni di cui sopra rendono vero. Suppongo di essere più preciso, ciò che mi confonde è il seguente: i valori stringa specificati nel pool costante (che sono riuscito a leggere usando il comando "javap -c -verbose ClassName.class" in cmd) diventano istanziato + caricato nel pool interno che è, come di Java 7, trovato nell'heap? Il pool costante è un'entità reale durante il runtime? (Scusa se la mia domanda è confusa, se è necessario chiarire, fammi sapere) – kylemart

+1

@KyleMart Il primo produce false. Provalo. Sto cercando di spiegare come funziona il pool 'intern()'. –

+0

Il mio male. Lol. Intendevo davvero dire che il primo delle due condizioni avrebbe dato false. Totalmente derped quando scrivevo il mio ultimo commento. La ragione per cui la prima condizione è falsa è perché var fa riferimento a una stringa nel pool interno mentre var b fa riferimento a una stringa sull'heap, giusto? La cosa che mi confonde è la relazione tra il pool interno e il pool costante. – kylemart

Problemi correlati