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

    Passaggio dei parametri: Problema.

    Codice PHP:
    public class zzz {

        public static 
    void main(String[] args) {
            
            
    String oggetto = new String();
            
    oggetto "valore 1";
            
            
    funzione1(oggetto);
            
            
    System.out.println("Oggetto contiene: '" oggetto "'");
        }
        
        public static 
    void funzione1(String str) {
            
    str "valore 2";
        }
        
        

    Come mai il risultato stampato sulla console è "valore 1" anzichè "valore 2"?
    Ho provato a documentarmi ed ho trovato questa pagina molto esaustiva, secondo la quale però il risultato del codice soprascritto dovrebbe essere "valore 2".

    In che cosa sbaglio?

    Grazie.
    Think global, act local.

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

    Re: Passaggio dei parametri: Problema.

    Originariamente inviato da index
    Ho provato a documentarmi ed ho trovato questa pagina molto esaustiva, secondo la quale però il risultato del codice soprascritto dovrebbe essere "valore 2".
    Ma lo spiega chiaramente:

    Comunque, il riferimento stesso e' passato per valore, cioe' viene fatta una copia del valore dell'indirizzo in memoria dell'oggetto.

    Cosi' se la variabile corrispondente nel metodo e' modificata, non si avra'alcun effetto sulla variabile originale.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328

    Moderazione

    Non ho capito la motivazione della segnalazione di questa discussione.
    Credo che andbin sia stato chiarissimo nel riportare quanto scritto nella pagina da te linkata... alla funzione viene passata una copia dell'indirizzo.
    Nel momento in cui tu vai a "modificare" l'oggetto, riassegnandogli qualcosa, tu cambi il puntatore (e in pratica vai a costruire un nuovo oggetto). Devi fare attenzione, comunque, con le stringhe perchè sono degli oggetti un po' particolari in quanto immutabili (quindi non possono essere modificati).

    Se effettui una prova diversa, utilizzando anche un oggetto di tipo diverso, ti accorgerai della differenza. Ad esempio, modificando solo un po' il tuo codice:
    codice:
    import java.util.Vector;
    
    public class zzz {
    
        public static void main(String[] args) {
            
            Vector oggetto = new Vector();
            oggetto.add("Primo");
    
            funzione1(oggetto);
            
            System.out.println("Oggetto contiene: '" + oggetto.elementAt(0) + "'");
        }
        
        public static void funzione1(Vector v) {
            v.remove(0);
            v.add("Secondo");
        }
        
    }
    In questo caso l'oggetto di tipo Vector è sempre e solo uno. Solo che nella funzione viene modificato (viene tolta dal vettore la prima stringa, che viene rimpiazzata da un'altra).


    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

  4. #4
    Hai ragione funziona!

    Ora però non riesco a capire perchè nel contesto originale... il mio codice non si comporti alla stessa maniera.

    PS. Quello che aveva scritto l'altro utente lo avevo capito, mi sfuggiva l'immutabilità dell'oggetto String. Era questa la risposta che cercavo.

    PPS. Ma se castassi uno string in object lo renderei mutabile?

    Grazie.
    Think global, act local.

  5. #5
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da index
    Ora però non riesco a capire perchè nel contesto originale... il mio codice non si comporti alla stessa maniera.
    Quello che hai postato sopra all'inizio?
    E cosa non ti è ancora chiaro?

    Originariamente inviato da index
    PPS. Ma se castassi uno string in object lo renderei mutabile?
    No assolutamente. Quello che cambi con un cast è solo il tipo "statico" del reference. Se un oggetto allocato sul heap è un String allora è e continua a rimanere un String fino alla sua "morte".

    Tornando alla questione della (im)mutabilità, un oggetto è immutabile se non esiste alcun modo (dopo la sua creazione) per alterare lo stato interno dell'oggetto. E per String è così. Nessuno dei suoi tanti metodi altera lo stato dell'oggetto, ogni metodo che compie qualche operazione di modifica in realtà restituisce un nuovo oggetto senza modificare lo stato dell'oggetto su cui è stato invocato il metodo.
    In più String è una classe final e questo assicura che nessuno possa alterare tramite estensione lo stato interno o il comportamento dei suoi metodi.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  6. #6
    Utente di HTML.it
    Registrato dal
    Apr 2007
    Messaggi
    906
    Ora però non riesco a capire perchè nel contesto originale... il mio codice non si comporti alla stessa maniera.
    PS. Quello che aveva scritto l'altro utente lo avevo capito, mi sfuggiva l'immutabilità dell'oggetto String. Era questa la risposta che cercavo.
    Credo invece che tu non abbia capito ciò che ha scritto andbin. Il non funzionamento non dipende da String.
    Quando tu passi un oggetto ad una funzione, crei in memoria un nuovo riferimento che punta a quell'oggetto. A questo punto hai 2 riferimenti, quello originale e quello del metodo, che puntano allo stesso oggetto. Se tu nel metodo modifichi l'oggetto (ad esempio attraverso i suoi stessi metodi), alla fine dell'esecuzione vedrai le modifiche. Se tu invece allochi un nuovo oggetto, fai in modo che il riferimento del metodo punti al un nuovo oggetto (ma il riferimento originale punta sempre all'oggetto vecchio), quindi qualsiasi modifica sara ininfluente una volta usciti dal metodo.
    Ho spiegato in maniera ingarbugliata, ti faccio un esempio:
    codice:
    import java.util.Vector;
    
    public class TestRiferimento {    
        public static void modObject1(Vector v2) {
            v = new Vector();
            v.add("modificato");
        }
        
        public static void modObject2(Vector v2) {
            v.remove(0);
            v.add("modificato");
        }
        
        public static void main(String[] args) {
            Vector v1 = new Vector();
            v.add("non modificato");
            System.out.println("Primo valore vector = "+v.get(0));
            modObject1(v);
            System.out.println("Primo valore vector dopo modObject1= "+v.get(0));
            modObject2(v);
            System.out.println("Primo valore vector dopo modObject2= "+v.get(0));
        }
    }
    La situazione e' questa: parte il main e tu in memoria hai il riferimento v1 che punta al Vettore X.

    v -> X

    Chiami il primo metodo di modifica, hai il riferimento v2 che punta al Vettore X.

    v1 -> X
    v2 -> X

    Nel metodo, crei un nuovo vettore Y e lo assegni a v2. Ora sei in questa situazione:

    v1-> X
    v2-> Y

    sempre nel metodo, modifichi il vettore puntato da v2, quindi Y. Mettiamo * per notificare lo stato di oggetto modificato.

    v1->X
    v2->Y*

    Una volta uscito dal primo metodo di modifica perdo il riferimento v2 e la situazione ritorna

    v1->X

    Ovviamente le cose cambiano nel secondo.

    v1->X
    v2->X

    Nel corpo del secondo modifichi direttamente il vettore puntato da v2, quindi X.

    v1->X*
    v2->X*

    All'uscita del metodo perdi il riferimento a v2, ma le modifiche, essendo state fatte ad X, sono visibili utilizzando il riferimento v1.

    v1->X*

    String e' un oggetto particolare. Come ti e' stato detto e' immutabile(non c'e' cast che possa modificare questa situazione) ed infatti, se guardi la documentazione, non troverai metodi che modificano direttamente la stringa, ma al massimo eseguono operazioni e ti restituiscono una nuova stringa. In situazioni come queste, considera String alla stregua di un dato primitivo (anche se non lo e').

  7. #7
    Grazie ora ho capito.
    Think global, act local.

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 © 2026 vBulletin Solutions, Inc. All rights reserved.