Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    [JAVA] le String sono immutabili?

    Salve,

    C'è un passo del mio libro che non capisco, ve lo sintetizzo:

    [...]
    Gli oggetti String java sono immutabili, ovvero non possono essere modificati dopo che sono stati creati (la classe String non fornisce alcun metodo set). Dato che un riferimento non può essere usato per modificare una String, è meglio avere molti riferimenti a un oggetto String all'interno di un programma Java.
    [...]

    questo dovrebbe significare che una volta che creo un oggetto String e gli passo un valore, poi se provo a modificarlo dovrebbe darmi errore, eppure se eseguo questo programma:

    Codice PHP:
    ...
    String s "ciao";
    "mondo";
    System.out.print(s);
    ... 
    non solo non mi da errori ma mi visualizza mondo.
    Cosa non ho capito?

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,283

    Re: [JAVA] le String sono immutabili?

    Originariamente inviato da mattew80
    Codice PHP:
    ...
    String s "ciao";
    "mondo";
    System.out.print(s);
    ... 
    non solo non mi da errori ma mi visualizza mondo.
    Cosa non ho capito?
    Un oggetto String è immutabile per un motivo molto semplice: tutti i metodi che effettuano delle modifiche (trim(), concat(), ecc....) NON modificano l'oggetto su cui è invocato il metodo ma creano e ritornano un nuovo String.

    Nel codice sopra, tra l'altro non invochi metodi di String, semplicemente assegni alla variabile 's' il reference ad un'altra stringa.

    Volendo fare un'altro esempio:

    String s = "hello";
    s.concat (" world");

    Questo codice non funziona, il metodo concat non modifica l'oggetto stringa "hello" ma ritorna un nuovo oggetto String. Non avendolo assegnato a una qualche variabile, viene perso e 's' continua a fare riferimento a "hello".

    Si fa quindi:

    String s = "hello";
    s = s.concat (" world");

    Che non vuol dire che hai modificato la stringa "hello" ma vuol dire che la variabile reference 's' fa poi riferimento ad un nuovo oggetto String che contiene "hello world".
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Ok, quindi riepilogando, se ho capito bene:

    Le stringhe in java sono degli oggetti della classe String. Come tutti gli oggetti si creano con l'operatore new.
    Codice PHP:
    String s = new String("Hello"); 
    Esiste anche una variante sintetica per la creazione di un oggetto String, che è la seguente:
    Codice PHP:
    String s "Hello"
    l'oggetto s fa quindi riferimento ad un area di memoria in cui si trova un oggetto di tipo String che contiene la stringa hello.
    Nel momento in cui faccio:
    Codice PHP:
    " World"
    in realtà non ho modificato l'oggetto originario che conteneva la stringa hello, bensì ho creato un nuovo oggetto String, facendo in modo che l'oggetto precedente (hello) venisse distrutto tramite il garbage collector e che la variabile reference s faccia ora riferimento ad una nuova area di memoria in cui si trova un nuovo oggetto di tipo String inizializzato con la stringa world.
    L'oggetto String, quindi, non subisce nessun tipo di modifica, in quanto il valore con cui l'ho inizializzato nel costruttore è immutabile. Al più posso creare un nuovo oggetto String, cambiandone il riferimento.

    Discorso analogo per i metodi della classe String, come concat, i quali non modificano le strighe, bensì ritornano un nuovo oggetto String usando, presumibilmente, valori temporanei per la modifica onde evitare di perdere la stringa originaria.

    Discorso inverso per i tipi elementari, come gli int, i cui valori vengono effettivamente modificati durante le assegnazioni.

    Ho capito bene? :master:

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,315
    Tutto perfetto.


    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

  5. #5
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,283
    Originariamente inviato da mattew80
    Codice PHP:
    String s = new String("Hello"); 
    Esiste anche una variante sintetica per la creazione di un oggetto String, che è la seguente:
    Codice PHP:
    String s "Hello"
    C'è una differenza sostanziale: nel primo caso ci sono 2 oggetti, nel secondo solo 1.
    Le stringhe "literal" (letterali) vengono messe in un "constant pool". Nel primo caso passi una stringa literal al costruttore di String e poi viene creato un nuovo String con lo stesso contenuto della stringa literal.

    Originariamente inviato da mattew80
    Nel momento in cui faccio:
    Codice PHP:
    " World"
    in realtà non ho modificato l'oggetto originario che conteneva la stringa hello, bensì ho creato un nuovo oggetto String, facendo in modo che l'oggetto precedente (hello) venisse distrutto tramite il garbage collector e che la variabile reference s faccia ora riferimento ad una nuova area di memoria in cui si trova un nuovo oggetto di tipo String inizializzato con la stringa world.
    Precisazione: le stringhe "literal" non vengono mai garbage-collected.

    Originariamente inviato da mattew80
    L'oggetto String, quindi, non subisce nessun tipo di modifica, in quanto il valore con cui l'ho inizializzato nel costruttore è immutabile.
    No, la mutabilità o immutabilità di un oggetto non dipende dal tipo di dato usato o da cosa si passa nel costruttore.
    Dipende da come è fatta la classe, cioè da come le variabili di istanza sono accessibili e da quali metodi ci sono e da cosa fanno con lo stato dell'oggetto.

    La seguente classe definisce oggetti immutabili:

    codice:
    class Intero
    {
        private int val;
    
        public Intero (int v) { val = v; }
        public int getValore () { return val; }
    }
    Il motivo è semplice: una volta creato un oggetto Intero, non ci sono metodi per modificare il suo stato e inoltre la variabile 'val' non è accessibile direttamente dall'esterno.

    Quello che segue adesso è mutabile:
    codice:
    class Intero
    {
        private int val;
    
        public Intero (int v) { val = v; }
        public int getValore () { return val; }
        public void addValore (int a) { val += a; }
    }
    Ora con il metodo addValore posso alterare lo stato dell'oggetto, quindi è mutabile.

    Quello che segue adesso è nuovamente immutabile, ha un metodo addValore che però non modifica lo stato ma bensì crea e restituisce un nuovo Intero modificato:

    codice:
    class Intero
    {
        private int val;
    
        public Intero (int v) { val = v; }
        public int getValore () { return val; }
        public Intero addValore (int a) { return new Intero (val+a); }
    }
    Quest'ultima è la stessa, identica, situazione della classe String.


    Originariamente inviato da mattew80
    Discorso analogo per i metodi della classe String, come concat, i quali non modificano le strighe, bensì ritornano un nuovo oggetto String usando, presumibilmente, valori temporanei per la modifica onde evitare di perdere la stringa originaria.
    Sì ma la stringa originale non viene persa ... non c'è questo "pericolo". La stringa è lo stato dell'oggetto e come si è detto, non viene toccato assolutamente.

    Originariamente inviato da mattew80
    Discorso inverso per i tipi elementari, come gli int, i cui valori vengono effettivamente modificati durante le assegnazioni.
    Anche le variabili di tipo reference vengono modificate durante la assegnazione. Ma in questo caso è il valore del reference a cambiare.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  6. #6
    Grazie tante a tutti.
    Sono nuovo e vi assicuro che i vostri aiuti mi sono fondamentali.
    In effetti se si rispettano le regole del forum è un servizio utilissimo.
    Spero solo di essere in grado di rispondere anche io agli altri utenti tra non molto


Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.