Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    442

    Passaggio paramentri per valore/riferimento

    Questo concetto mi rimane oscuro

    Primitive arguments, such as an int or a double, are passed into methods by value. This means that any changes to the values of the parameters exist only within the scope of the method. When the method returns, the parameters are gone and any changes to them are lost. Here is an example:

    codice:
    public class PassPrimitiveByValue {
        public static void main(String[] args) {
            int x = 3;
            // invoke passMethod() with 
            // x as argument
            passMethod(x);
            // print x to see if its 
            // value has changed
            System.out.println("After invoking passMethod, x = " + x);
        }
        // change parameter in passMethod()
        public static void passMethod(int p) {
            p = 10;
        }
    }
    When you run this program, the output is:
    After invoking passMethod, x = 3

    Non riesco a capire il razionale di questa cosa.


    Ho anche questo esempio:

    codice:
    class Parametri {
    	static void inc(int x) {
    		x++;
    		}
    	public static void main (String[] args) {
    		int y=0;
    		inc(y);
    		System.out.println(y); //ritorna 0
    	}
    }
    codice:
    class Parametri {
    	static int inc(int x) {
    		x=x+1;
    		return x;
    		}
    	public static void main (String[] args) {
    		int y=0;
    		y=inc(y);
    		System.out.println(y); //ritorna 1
    	}
    }
    Perché il primo non funziona e il secondo sì??
    Sarò tonta ma non ci arrivo proprio, se qualcuno ha voglia di farmi capire questa cosa, gliene sono grata.

  2. #2
    Utente di HTML.it
    Registrato dal
    Dec 2009
    Messaggi
    613

    Re: Passaggio paramentri per valore/riferimento

    Originariamente inviato da Jamie04
    Questo concetto mi rimane oscuro

    Primitive arguments, such as an int or a double, are passed into methods by value. This means that any changes to the values of the parameters exist only within the scope of the method. When the method returns, the parameters are gone and any changes to them are lost. Here is an example:

    codice:
    public class PassPrimitiveByValue {
        public static void main(String[] args) {
            int x = 3;
            // invoke passMethod() with 
            // x as argument
            passMethod(x);
            // print x to see if its 
            // value has changed
            System.out.println("After invoking passMethod, x = " + x);
        }
        // change parameter in passMethod()
        public static void passMethod(int p) {
            p = 10;
        }
    }
    When you run this program, the output is:
    After invoking passMethod, x = 3

    Non riesco a capire il razionale di questa cosa.


    Ho anche questo esempio:

    codice:
    class Parametri {
    	static void inc(int x) {
    		x++;
    		}
    	public static void main (String[] args) {
    		int y=0;
    		inc(y);
    		System.out.println(y); //ritorna 0
    	}
    }
    codice:
    class Parametri {
    	static int inc(int x) {
    		x=x+1;
    		return x;
    		}
    	public static void main (String[] args) {
    		int y=0;
    		y=inc(y);
    		System.out.println(y); //ritorna 1
    	}
    }
    Perché il primo non funziona e il secondo sì??
    Sarò tonta ma non ci arrivo proprio, se qualcuno ha voglia di farmi capire questa cosa, gliene sono grata.
    I due esempi sono completamente diversi: inc(y) ritorna y+1 (ma non lo salva da nessuna parte, perdendolo), mentre y=inc(y) assegna il risultato di inc(y) (ovvero y+1) a y, di fatto incrementandolo. Non è inc() che incrementa (non potrebbe farlo, come dice il testo che citi), sei tu che nel secondo caso modifichi y assegnandogli un nuovo valore.
    effeffe

  3. #3
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,327
    Vediamo cosa accade in memoria con il primo codice (il secondo è uguale, solo che invece di assegnare 10, si incrementa):

    All'inizio nello stack c'è un solo valore (il 3) puntato dalla variabile locale al main chiamata "x"
    Viene chiamato il metodo, quindi si crea una nuova posizione nello stack, puntata dalla variabile locale al metodo "p". In questa nuova posizione viene copiato il valore del parametro passato. Quindi "x" punta ad una posizione con valore 3 e "p" punta ad un'altra posizione (diversa) contenente il valore 3. A questo punto nella posizione puntata da "p" viene messo il valore 10: si noti che nella posizione puntata da "x" c'è sempre il 3, non viene toccato. Il metodo ora termina, la posizione puntata da "p" viene buttata via. "x" vale ancora 3, perchè nessuno lo ha toccato.

    Vediamo ora cosa accade nel secondo caso: qui le cose cambiano leggermente. Viene fatto tutto come nel precedente caso, tranne che alla fine il valore non viene "buttato via", ma viene restituito al chiamante. Il chiamante, infatti, non fa semplicemente una chiamata al metodo, ma assegna il valore di ritorno alla stessa variabile:

    codice:
    // chiamo il metodo "inc", che non ritorna nulla
    // e se anche ritornasse qualcosa, questo qualcosa lo butto via
    inc( x );
    
    // chiamo il metodo "inc" ed il suo valore di ritorno lo assegno
    // alla variabile "x", che quindi cambia il suo valore
    x = inc( x );

    Spero sia un po' più chiaro.

    PS: in Java esiste solo il passaggio per valore. Anche gli oggetti vengono passati per valore, ma essendo solo dei "riferimenti", quel che viene passato è il valore del riferimento... per cui, eventuali modifiche apportate all'oggetto sono visibili al chiamante, perchè effettuate tramite un "riferimento".


    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
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    442
    Originariamente inviato da LeleFT
    Il metodo ora termina, la posizione puntata da "p" viene buttata via. "x" vale ancora 3, perchè nessuno lo ha toccato.
    perché p viene buttato via? quando termina un metodo viene liberato lo stack occupato dalle sue variabili?
    ti ringrazio, ora finalmente ho capito

    Originariamente inviato da LeleFT
    PS: in Java esiste solo il passaggio per valore. Anche gli oggetti vengono passati per valore, ma essendo solo dei "riferimenti", quel che viene passato è il valore del riferimento... per cui, eventuali modifiche apportate all'oggetto sono visibili al chiamante, perchè effettuate tramite un "riferimento".
    quindi, con gli oggetti succede l'esatto contrario? il valore modificato viene mantenuto?

    grazie!

  5. #5
    Utente di HTML.it
    Registrato dal
    Dec 2009
    Messaggi
    613
    Originariamente inviato da Jamie04
    perché p viene buttato via? quando termina un metodo viene liberato lo stack occupato dalle sue variabili?
    ti ringrazio, ora finalmente ho capito



    quindi, con gli oggetti succede l'esatto contrario? il valore modificato viene mantenuto?

    grazie!
    (mi permetto d'intromettermi)

    Sì, la vita delle variabili locali termina quando di esce dal blocco all'interno del quale sono state definite, in questo caso il metodo. E sì, i metodi possono modificare i parametri che ricevono se essi sono oggetti, ed ovviamente se tali oggetti sono modificabili (chiaro che non si possa modificare una variabile privata di un oggetto se esso non fornisce i metodi per farlo). Ma in realtà non succede niente di diverso: le variabili di tipi primitivi contengono il dato vero e proprio, mentre le variabili che hanno per tipo una qualche classe contengono l'indirizzo dell'oggetto, non l'oggetto: quindi copiando un tipo primitivo copi il valore (e le modifiche vengono effettuate sulla copia e non sull'originale) mentre copiando un oggetto quello che viene copiato e il riferimento a quest'oggetto, risultando quindi in un solo ed unico oggetto in memoria puntato da entrambi i riferimenti: per questo l'oggetto può essere modificato tramite entrambi i riferimenti.

    Probabilmente dei disegni aiutano: http://stackoverflow.com/a/12429953/1202636
    effeffe

  6. #6
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    442
    Grazie, ora è più chiaro, anche se faccio fatica a memorizzare queste cose

    Avrei bisogno di un chiarimento su questo passaggio:

    To access a field, you can use a named reference to an object, as in the previous examples, or you can use any expression that returns an object reference. Recall that the new operator returns a reference to an object. So you could use the value returned from new to access a new object's fields:

    int height = new Rectangle().height;


    Non capisco cosa significa che l'operatore new ritorna la referenza a un oggetto. Esempio in questa istruzione:

    Rectangle rect1=new Rectangle(10,15);

    la referenza all'oggetto rectangle è "rect1", o no?
    mentre qui:
    int height = new Rectangle().height;

    la referenza non è "height"?

    E ancora:

    This (int height = new Rectangle().height statement creates a new Rectangle object and immediately gets its height. In essence, the statement calculates the default height of a Rectangle. Note that after this statement has been executed, the program no longer has a reference to the created Rectangle, because the program never stored the reference anywhere. The object is unreferenced, and its resources are free to be recycled by the Java Virtual Machine.

    Anche qui non capisco...
    Se l'oggetto creato con questa istruzione:
    int height = new Rectangle().height;
    viene "perso" dopo l'esecuzione dell'istruzione, a cosa potrebbe mai servire fare una cosa del genere?
    Perdo l'oggetto rettangolo ma mi rimane una variabile intera height?
    Forse se mi fate qualche esempio in cui queste istruzioni tornano utili mi rimane più comprensibile...

    Grazie a tutti!

  7. #7
    Utente di HTML.it
    Registrato dal
    Dec 2009
    Messaggi
    613
    Originariamente inviato da Jamie04
    Grazie, ora è più chiaro, anche se faccio fatica a memorizzare queste cose

    Avrei bisogno di un chiarimento su questo passaggio:

    To access a field, you can use a named reference to an object, as in the previous examples, or you can use any expression that returns an object reference. Recall that the new operator returns a reference to an object. So you could use the value returned from new to access a new object's fields:

    int height = new Rectangle().height;


    Non capisco cosa significa che l'operatore new ritorna la referenza a un oggetto. Esempio in questa istruzione:

    Rectangle rect1=new Rectangle(10,15);

    la referenza all'oggetto rectangle è "rect1", o no?
    mentre qui:
    int height = new Rectangle().height;

    la referenza non è "height"?

    E ancora:

    This (int height = new Rectangle().height statement creates a new Rectangle object and immediately gets its height. In essence, the statement calculates the default height of a Rectangle. Note that after this statement has been executed, the program no longer has a reference to the created Rectangle, because the program never stored the reference anywhere. The object is unreferenced, and its resources are free to be recycled by the Java Virtual Machine.

    Anche qui non capisco...
    Se l'oggetto creato con questa istruzione:
    int height = new Rectangle().height;
    viene "perso" dopo l'esecuzione dell'istruzione, a cosa potrebbe mai servire fare una cosa del genere?
    Perdo l'oggetto rettangolo ma mi rimane una variabile intera height?
    Forse se mi fate qualche esempio in cui queste istruzioni tornano utili mi rimane più comprensibile...

    Grazie a tutti!
    Non c'è granché da memorizzare, il passaggio è sempre per valore, basta sapere che esistono i tipi primitivi e i reference.

    I reference sono i riferimenti agli oggetti. Nel secondo esempio la referenza (anonima) è il valore restituito da new Rectangle(). Come potrebbe height essere un riferimento ad un oggetto Rectangle? L'height a sinistra dell'uguale lo stai dichiarando tu stesso come int, e quello a destra è un campo della classe Rectangle, probabilmente di tipo int.

    Le referenze con un nome sono le variabili che rappresentano oggetti (quindi di tipo String, Rectangle ecc...), mentre quelle anonime sono le creazioni "al volo" di tali oggetti, che non essendo salvati da nessuna parte possono sparire subito dopo.

    E sì, con l'ultimo esempio perdi immediatamente il riferimento all'oggetto Rectangle appena creato. Con una classe del genere è difficile vederne l'utilità, ma considera la classe Random col metodo nextInt(): se ti serve solo un intero casuale, perché fare questo:

    codice:
    Random random = new Random();
    int randomValue = random.nextInt();
    anziché questo?

    codice:
    int randomValue = new Random().nextInt();
    Col secondo metodo guadagni in semplicità e in efficienza. La variabile int invece rimane perfettamente valida, perché l'oggetto viene distrutto dopo che il metodo restituisce il valore, che può quindi essere assegnato senza nessun problema.

    Purtroppo è diffuso il brutto vizio di non fornire esempi sensati...
    effeffe

  8. #8
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    442
    Ho capito (spero), l'ultimo esempio che hai fatto è decisamente più ragionevole... in pratica questo tipo di istruzioni servono quando l'oggetto in sè non è importante ma lo è uno dei suoi campi...perché l'oggetto Random non è altro che un numero generato casualmente da una classe che per fare questo crea degli oggetti... non so se mi sono spiegata
    In pratica è un sistema che si usa per "sfruttare" il campo di un oggetto che fa al caso nostro quando non è conveniente stare a definire un qualche metodo per generare questo valore...
    Ci sono?
    Thanks!

  9. #9
    Utente di HTML.it
    Registrato dal
    Dec 2009
    Messaggi
    613
    Originariamente inviato da Jamie04
    Ho capito (spero), l'ultimo esempio che hai fatto è decisamente più ragionevole... in pratica questo tipo di istruzioni servono quando l'oggetto in sè non è importante ma lo è uno dei suoi campi...perché l'oggetto Random non è altro che un numero generato casualmente da una classe che per fare questo crea degli oggetti... non so se mi sono spiegata
    In pratica è un sistema che si usa per "sfruttare" il campo di un oggetto che fa al caso nostro quando non è conveniente stare a definire un qualche metodo per generare questo valore...
    Ci sono?
    Thanks!
    Nella stragrande maggioranza dei casi sugli oggetti anonimi s'invocano i metodi piuttosto che leggere i campi (come nel mio esempio del resto), comunque sì, il senso è quello.
    effeffe

  10. #10
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    442
    Cosa sono gli oggetti anonimi Oggetti non referenziati?
    Ultima domanda (per oggi ):
    a che serve il this coi costruttori? Ho capito cosa fa, serve a un costruttore per invocare un altro costruttore, ma perché? A che serve una cosa del genere?
    A cosa mi serve un costruttore che invoca un altro costruttore?

    Grazie!

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.