P.java

/* In java i tipi di dato primitivo sono allocati sullo stack, mentre
 * le classi sono allocate sullo heap e vengono accedute tramite
 * reference. Chiaramente la semantica del passaggio parametri
 * rispetta questa differenze: i dati primitivi sono passati per copia
 * (il valore della cella e' copiato nell'activation record della
 * funzione) mentre le classi sono passati per reference (il valore
 * della reference e' copiato nell' AR e quindi in memoria esiste una
 * sola istanza dell'oggetto).  In altre parole nel caso delle classi
 * e' la reference che viene copiata per valore.  Questo spiega perche'
 * modifyA non modifica l'oggetto pippo mentre modifyList
 * si. Tuttavia, se durante la funzione eseguo un nuovo binding (vedi
 * createList), questa operazione non si ripercuote sul main perche'
 * sto cambiando il valore della reference locale (cioe' nell'AR della
 * funzione) e non quella del main. In modifyList invece modifico
 * direttamente l'oggetto list che e' referenziato sia dalla reference
 * nell'AR sia da quella del main e pertanto le modifiche sono
 * visibili ad entrambi.
 */

import java.util.LinkedList;
import java.util.List;

class Helper {
    static public void modifyA(int x) {
	x = 666;
    }

    static public void createList(List list) {
	list = new LinkedList();
	list.add(new Integer(666));
	list.add(new Integer(666));
	list.add(new Integer(666));
		
    }

    static public void modifyList(List list) {
	list.add(new Integer(666));
    }

}

public class P {

    private int a;

    private List list;

    public P(int a, List list) {
	this.a = a;
	this.list = list;
    }

    public int getA() {
	return a;
    }

    public List getList() {
	return list;
    }

    public static void main(String[] args) {
	P pippo = new P(5, new LinkedList());

	System.out.println("pippo (" + pippo + "): list vale "
			   + pippo.getList() + " e a vale " + pippo.getA());

	Helper.modifyA(pippo.a); // passaggio per valore
	Helper.modifyList(pippo.list); // passaggio per riferimento

	System.out.println("pippo (" + pippo + "): list vale "
			   + pippo.getList() + " e a vale " + pippo.getA());
		
	Helper.createList(pippo.list); // creo un nuovo binding (una lista con 3 volte 666)
		
	System.out.println("pippo (" + pippo + "): list vale "
			   + pippo.getList() + " e a vale " + pippo.getA()); // l'oggetto e' rimasto immutato

    }

}

Generated by GNU enscript 1.6.4.