queste 2 parti di codice, per dichiarare e inizializzare una stringa, sono equivalenti?
codice:String varX= "ciao ciao";oppure fanno rispettivamente parte di diverse revisioni di Java?codice:String varX= new String("ciao ciao");
queste 2 parti di codice, per dichiarare e inizializzare una stringa, sono equivalenti?
codice:String varX= "ciao ciao";oppure fanno rispettivamente parte di diverse revisioni di Java?codice:String varX= new String("ciao ciao");
No ai layout tabellari!
Insulto libero: http://forum.html.it/forum/showthread.php?s=&postid=12524872#post12524872
oltre alla considerazione di quanti oggetti si creano:
String s = new String("pippo");
equivale a
1. creare la stringa pippo (la jvm deve averne una rappresentazione)
2. creare l'oggetto s che inizialmente ha una stringa vuota
3. copiare l'oggetto pippo in s
questo è quanto riportano i sorgenti java riguardo a string.codice:/** * Initializes a newly created <code>String</code> object so that it * represents the same sequence of characters as the argument; in other * words, the newly created string is a copy of the argument string. Unless * an explicit copy of <code>original</code> is needed, use of this * constructor is unnecessary since Strings are immutable. * * @param original a <code>String</code>. */ public String(String original) { int size = original.count; char[] originalValue = original.value; char[] v; if (originalValue.length > size) { // The array representing the String is bigger than the new // String itself. Perhaps this constructor is being called // in order to trim the baggage, so make a copy of the array. v = new char[size]; System.arraycopy(originalValue, original.offset, v, 0, size); } else { // The array representing the String is the same // size as the String, so no point in making a copy. v = originalValue; } this.offset = 0; this.count = size; this.value = v; }
Poi in base a quanto riportato sopra ci saranno ottimizzazioni sull'uso delle stringhe in memoria, ma anche questa è una delle ragioni per non usare questo costrutto
@Freax... a meno che non ci siano delle ottime ragioni per voler tenere distinti due oggetti con lo stesso contenuto. Prova questi test:Originariamente inviato da valia
Poi in base a quanto riportato sopra ci saranno ottimizzazioni sull'uso delle stringhe in memoria, ma anche questa è una delle ragioni per non usare questo costrutto
Ciao.codice:String s1 = "CIAO"; String s2 = "CIAO"; String s3 = new String("CIAO"); String s4 = new String("CIAO"); System.out.println(s1 == s2); System.out.println(s1 == s3); System.out.println(s3 == s4); System.out.println(s1.equals(s3)); System.out.println(s3.equals(s4));![]()
"Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza
quindi, in sostanza, uso più memoria, alloco un oggetto in più, e quindi una inizializzazione di una classe String in più, giusto?
vedila così: che bisogno hai di creare un oggetto e clonarlo per avere quello di partenza?
A meno di particolari esigenze non usare questo approccio
correggetemi se sbaglio, con
io ho una costante che viene clonata come variabile di istanza?codice:String varX= new String("ciao ciao");
dal punto di vista della memoria, quindi, "ciao ciao" e varX, fanno riferimento a 2 indirizzi differenti con proprietà di modifica differenti ?
a dire la verità non mi è chiarissimo il concetto ma inizio a comprenderne i "margini di manovra", mi mancano gli ultimi capitoli dal libro e forse quelli mi aiuteranno![]()
no, tu hai una rappresentazione interna di ciao ciao che viene clonata per creare la tua stringa, roba inutile nel 95% delle situazioni in cui basta fare solo un assegnamento.
Passare per il costruttore significa creare 2 oggetti con riferimenti diversi che hanno lo stesso contenuto (inefficiente appunto)
ma io ciao ciao lo passo come costante, che senso ha dire che ci sono 2 oggetti? dopo quella chiamata la costante "ciao ciao" non dovrebbe essere eliminata dal garbage collector e quindi in memoria mi ritrovo con 1 solo oggetto ovvero varX?Originariamente inviato da valia
no, tu hai una rappresentazione interna di ciao ciao che viene clonata per creare la tua stringa, roba inutile nel 95% delle situazioni in cui basta fare solo un assegnamento.
Passare per il costruttore significa creare 2 oggetti con riferimenti diversi che hanno lo stesso contenuto (inefficiente appunto)
Devi partire da un concetto fondamentale riguardante le stringhe: esse sono immutabili. Cioè sono oggetti che non possono essere modificati.Originariamente inviato da Freax
correggetemi se sbaglio, con
io ho una costante che viene clonata come variabile di istanza?codice:String varX= new String("ciao ciao");
dal punto di vista della memoria, quindi, "ciao ciao" e varX, fanno riferimento a 2 indirizzi differenti con proprietà di modifica differenti ?
a dire la verità non mi è chiarissimo il concetto ma inizio a comprenderne i "margini di manovra", mi mancano gli ultimi capitoli dal libro e forse quelli mi aiuteranno![]()
Non ho ben capito cosa significhi per te "proprietà di modifica differenti", ma nel caso delle stringhe, tutte hanno la stessa capacità di modifica: nulla, assente, impossibile, niet.
Il discorso sulle stringhe in Java è piuttosto complesso, cercherò di riassumerlo:
Vi sono sostanzialmente 2 tipi di stringa: la stringa literal e la stringa non literal (se vogliamo darle un nome). Le stringhe literal sono tutte quelle che tu scrivi dentro al sorgente (ovvero, ogni volta che apri le virgolette, scrivi qualcosa e chiudi le virgolette, stai costruendo una stringa literal). Le altre (non literal) sono stringhe che provengono dall'esterno del sorgente (lette in input dalla tastiera, da un file, da una connessione via socket, ecc) e di cui, quindi, il compilatore non è a conoscenza del contenuto.
Tutte le stringhe literal finiscono nello String Literal Pool: è una lista di riferimenti, dove ciascun riferimento punta ad un oggetto String presente nello heap (come tutti gli oggetti).
Quindi, con questa istruzione
crei due oggetti: uno è la stringa literal "Mia Stringa" (che va a finire nello String Literal Pool) e l'altro è un secondo oggetto del tutto identico al primo (dal punto di vista del contenuto), ma puntato solo dal reference "pippo".codice:String pippo = new String("Mia Stringa");
Queste due istruzioni
creano due reference (strA e strB), che puntano entrambi all'unico oggetto presente nello heap (e puntato sempre da un reference nello String Literal Pool) perchè entrambi si riferiscono allo stesso literal.codice:String strA = "Mia Stringa"; String strB = "Mia Stringa";
Credo che questo documento ti possa chiarire molto le idee.
Ciao.![]()
"Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza