JavaRush /Java Blog /Random-IT /Traduzione: creazione di oggetti String in Java - utilizz...
FellowSparrow
Livello 12
Lvov

Traduzione: creazione di oggetti String in Java - utilizzando " " o costruttore?

Pubblicato nel gruppo Random-IT
Originale: crea una stringa Java utilizzando " " o Costruttore? Di X Wang Traduzione: creazione di oggetti stringa in Java - UtilizzoIn Java, una stringa può essere creata utilizzando due metodi:
String x = "abc";
String y = new String("abc");
Qual è la differenza tra l'uso delle virgolette doppie e l'uso di un costruttore?

1. Virgolette doppie vs. Costruttore

A questa domanda si può rispondere guardando due semplici esempi. Esempio 1:
String a = "abcd";
String b = "abcd";
System.out.println(a == b);  // True
System.out.println(a.equals(b)); // True
a==btrue perché aentrambi bsi riferiscono allo stesso oggetto: una stringa dichiarata come letterale (stringa letterale di seguito) nell'area del metodo (rimandiamo il lettore alla fonte sulla nostra risorsa: Top 8 diagrammi per comprendere Java , diagramma 8). Quando la stessa stringa letterale viene creata più di una volta, in memoria viene archiviata solo una copia della stringa, solo una sua istanza (nel nostro caso "abcd"). Questo si chiama "internamento di stringhe". Tutte le costanti stringa elaborate in fase di compilazione vengono automaticamente internate in Java. Esempio 2:
String c = new String("abcd");
String d = new String("abcd");
System.out.println(c == d);  // False
System.out.println(c.equals(d)); // True
c==dfalse perché csi driferiscono a due oggetti diversi in memoria (nell'heap). Oggetti diversi hanno sempre riferimenti diversi. Questo diagramma illustra le due situazioni sopra descritte: Traduzione: creazione di oggetti stringa in Java - Utilizzo

2. Interning di stringhe in fase di esecuzione del programma

L'autore ringrazia LukasEder (il commento sotto è suo): L'internamento delle stringhe può verificarsi anche durante l'esecuzione del programma, anche se due stringhe vengono create utilizzando i costruttori:
String c = new String("abcd").intern();
String d = new String("abcd").intern();
System.out.println(c == d);  // Now true
System.out.println(c.equals(d)); // True

3. Quando utilizzare le virgolette doppie e quando utilizzare i costruttori

Dato che il valore letterale "abcd" è sempre di tipo String, l'utilizzo di un costruttore creerà un oggetto aggiuntivo non necessario. Quindi è necessario utilizzare le virgolette doppie se è necessario creare solo una stringa. Se hai effettivamente bisogno di creare un nuovo oggetto nell'heap, dovresti usare un costruttore. I casi d'uso sono mostrati qui (originale) . (Fornisco il testo tradotto di seguito. Ma ti consiglio comunque vivamente di familiarizzare con il codice dei commentatori a questo link.)

Il metodo substring() in JDK 6 e JDK 7

Il metodo substring() in JDK 6 e JDK 7 Di X Wang Il metodo substring(int beginIndex, int endIndex)in JDK 6 e JDK 7 è diverso. Conoscere queste differenze può aiutarti a utilizzare meglio questo metodo. Per comodità di lettura, di seguito substring()intendiamo la sintassi completa, ovvero substring(int beginIndex, int endIndex).

1. Cosa fa substring()?

Il metodo substring(int beginIndex, int endIndex)restituisce una stringa che inizia con il carattere numero beginIndexe termina con il carattere numero endIndex-1.
String x = "abcdef";
x = x.substring(1,3);
System.out.println(x);
Produzione:
bc

2. Cosa succede quando viene chiamata substring()?

Potresti sapere che, a causa dell'immutabilità x, quando si assegna x il risultato di x.substring(1,3), xpunta a una riga completamente nuova (vedi diagramma): Traduzione: creazione di oggetti stringa in Java - UtilizzoTuttavia, questo diagramma non è completamente corretto; non dimostra cosa sta realmente succedendo nell'heap. Ciò che accade effettivamente quando viene chiamato substring()è diverso in JDK 6 e JDK 7.

3. sottostringa() in JDK 6

Il tipo stringa è supportato dal tipo array char. In JDK 6, la classe Stringcontiene 3 campi: char value[], int offset, int count. Vengono utilizzati per memorizzare l'effettivo array di caratteri, l'indice del primo carattere nell'array, il numero di caratteri nella riga. Quando il metodo viene chiamato substring(), crea una nuova riga, ma il valore della variabile punta ancora allo stesso array nell'heap. La differenza tra due stringhe è il numero di caratteri e il valore di indice del carattere iniziale nell'array. Traduzione: creazione di oggetti stringa in Java - UtilizzoIl codice seguente è semplificato e contiene solo le nozioni di base per dimostrare il problema.
//JDK 6
String(int offset, int count, char value[]) {
	this.value = value;
	this.offset = offset;
	this.count = count;
}

public String substring(int beginIndex, int endIndex) {
	//check boundary
	return  new String(offset + beginIndex, endIndex - beginIndex, value);
}

4. Problema causato da substring() in JDK 6

Se hai una stringa MOLTO lunga, ma ti serve solo una piccola parte, che ottieni ogni volta usando substring(). Ciò causerà problemi di esecuzione, poiché è necessaria solo una piccola parte, ma è comunque necessario memorizzare l'intera stringa. Per JDK 6, la soluzione è il codice seguente, che trasformerà la stringa in una sottostringa reale:
x = x.substring(x, y) + ""
L'utente STepeR ha formulato una domanda (vedi suo commento), e ci è sembrato necessario aggiungere il punto 4. "Problema causato substring()in JDK 6" è un esempio più ampio. Spero che questa sia la risposta e aiuti gli altri a capire rapidamente qual è il problema. Ecco il codice:
String a = "aLongLongString";
String b = a.substring(1, 2);
String c = a.substring(2, 6);
Pertanto, in JDK 7 b, gli oggetti сdi tipo a Stringcreati chiamando un metodo substring()su un oggetto di tipo a Stringfaranno riferimento a due array appena creati nell'heap - Lfor b, ongLfor c. Questi due nuovi array verranno archiviati nell'heap INSIEME all'array originale a aLongLongStringcui fa riferimento a. Quelli. l'array originale non scompare da nessuna parte. Ora torniamo a JDK 6. In JDK 6, un heap contiene un singolo array aLongLongString. Dopo aver eseguito le righe di codice
String b = a.substring(1, 2);
String c = a.substring(2, 6);
gli oggetti bsi riferiscono callo stesso array nell'heap, corrispondente all'oggetto a: b- agli elementi dal 1° indice al 2°, c- agli elementi dal 2° indice al 6° (la numerazione inizia da 0, promemoria). Quelli. Ovviamente, qualsiasi ulteriore accesso alle variabili bo c in JDK 6 comporterà effettivamente il "conteggio" degli elementi desiderati dell'array originale nell'heap. In JDK 7, qualsiasi ulteriore accesso alle variabili bo c causerà l'accesso agli array più piccoli necessari che sono già stati creati e "vivi" nell'heap. Quelli. Chiaramente JDK 7 utilizza fisicamente più memoria in situazioni come questa. Ma immaginiamo una possibile opzione: alcune sottostringhe della variabile sono assegnate alle variabili be in futuro tutti le utilizzeranno solo: oggetti e . Nessuno accede più semplicemente alla variabile a; non ci sono riferimenti ad essa (questo intende l'autore dell'articolo). Di conseguenza, ad un certo punto viene attivato il garbage collector e (nella forma più generale, ovviamente) otteniamo 2 situazioni diverse: JDK 6 : l'oggetto viene distrutto (garbage collection) , MA - l'enorme array originale nel mucchio è vivo; è costantemente utilizzato e . JDK 7: l'oggetto a viene distrutto insieme all'array originale nell'heap. Questo è il punto in JDK 6 che può portare a una perdita di memoria. cabcabc

5. sottostringa() in JDK 7

Il metodo è stato migliorato in JDK 7. In JDK 7 substring()crea effettivamente un nuovo array nell'heap. Traduzione: creazione di oggetti stringa in Java - Utilizzo
//JDK 7
public String(char value[], int offset, int count) {
	//check boundary
	this.value = Arrays.copyOfRange(value, offset, offset + count);
}

public String substring(int beginIndex, int endIndex) {
	//check boundary
	int subLen = endIndex - beginIndex;
	return new String(value, beginIndex, subLen);
}
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION