PDA

View Full Version : [JAVA] swap e passaggio per copia


australopiteci
17-04-2009, 19:15
salve a tutti, ho letto che in java esiste il solo passaggio per copia.. anche i riferimenti vengono passati per copia. Non capisco allora l'output del seguente codice:

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package javaapplication1;





/**
*
* @author Administrator
*/
public class Main {


public static class Prova
{
int x;
int y;
Prova (int xx,int yy)
{
x=xx;
y=yy;
}
}

private static void swap(Prova a, Prova b)
{
System.out.println("DENTRO PRIMA: uno= " + a.x + " due= " + b.x );
Prova temp;
temp=a;
a=b;
b=temp;
System.out.println("DENTRO DOPO: uno= " + a.x + " due= " + b.x );
}

private static void change(Prova a, Prova b)
{
a.x=999999999;
b.x=999999999;
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here

System.out.println("Hello World!");

Prova uno,due;

uno = new Prova(1,1);
due = new Prova(2,2);
System.out.println("PRIMA: uno= " + uno.x + " due= " + due.x );
swap(uno,due);
System.out.println("DOPO: uno= " + uno.x + " due= " + due.x );


change(uno,due);
System.out.println("DOPO ANZ: uno= " + uno.x + " due= " + due.x );
}



}




Non capisco perchè la funzione change funzioni e la funzione swap no.
Che significa copiare i riferimenti?
alla fine anche se copio l'indirizzo (il riferimento) di un oggetto X, se vi accedo, accederò allo stesso oggetto.. non ad una copia dell'oggetto (perchè non lo creo da nessuna parte con l'operatore new..)

PGI-Bis
17-04-2009, 19:41
all'oggetto accedi dereferenziando (termine orrendo) il puntatore. a e b sono puntatori, l'invocazione crea una copia di quel puntatore, ottieni due puntatori il cui valore è lo stesso indirizzo.

La differenza sta nel ri-assegnamento. Se nel metodo scrivi a = new Prova() cambi il valore della copia del puntatore usata nel metodo ma non il valore di quello che hai usato per l'invocazione.

australopiteci
17-04-2009, 23:37
all'oggetto accedi dereferenziando (termine orrendo) il puntatore. a e b sono puntatori, l'invocazione crea una copia di quel puntatore, ottieni due puntatori il cui valore è lo stesso indirizzo.

La differenza sta nel ri-assegnamento. Se nel metodo scrivi a = new Prova() cambi il valore della copia del puntatore usata nel metodo ma non il valore di quello che hai usato per l'invocazione.

si ok, ma in swap non uso nessuna new e nemmeno in change.. però i due effetti sono diversi.. col primo non modifico i due oggetti, col secondo si..

wingman87
18-04-2009, 00:14
Nella swap scambi i valori dei puntatori all'interno del metodo, ma questi sono solo delle copie dei puntatori originali, quindi all'esterno del metodo non è accaduto nulla.
Nella change invece accedi tramite il puntatore ad un attributo dell'oggetto e lo modifichi.

EDIT: avevo scambiato change e swap, sorry

PGI-Bis
18-04-2009, 00:36
si ok, ma in swap non uso nessuna new e nemmeno in change.. però i due effetti sono diversi.. col primo non modifico i due oggetti, col secondo si..

Ma non modifichi l'oggetto per via del passaggio, modifichi l'oggetto per via della dereferenziazione

australopiteci
18-04-2009, 11:05
ok ragazzi ho capito, grazie mille..

la swap allora è possibile :)


/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package javaapplication1;





/**
*
* @author Administrator
*/
public class Main {


public static class Prova
{
int x;
int y;
Prova (int xx,int yy)
{
x=xx;
y=yy;
}
}

private static void swap(Prova a, Prova b)
{
System.out.println("DENTRO PRIMA: uno= " + a.x + " due= " + b.x );
Prova temp;
temp=a;
a=b;
b=temp;
System.out.println("DENTRO DOPO: uno= " + a.x + " due= " + b.x );
}

private static void swap2(Prova a, Prova b)
{
System.out.println("sw2 DENTRO PRIMA: uno= " + a.x + " due= " + b.x );
Prova temp = new Prova(0,0);
temp.x=a.x;

a.x=b.x;
b.x=temp.x;
System.out.println("sw2 DENTRO DOPO: uno= " + a.x + " due= " + b.x );
}


private static void change(Prova a, Prova b)
{
a.x=999999999;
b.x=999999999;
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here

System.out.println("Hello World!");

Prova uno,due;

uno = new Prova(1,1);
due = new Prova(2,2);
System.out.println("PRIMA: uno= " + uno.x + " due= " + due.x );
swap(uno,due);
System.out.println("DOPO: uno= " + uno.x + " due= " + due.x );


//change(uno,due);
//System.out.println("DOPO ANZ: uno= " + uno.x + " due= " + due.x );



System.out.println("sw2 X PRIMA: uno= " + uno.x + " due= " + due.x );
swap2(uno,due);
System.out.println("sw2 X DOPO: uno= " + uno.x + " due= " + due.x );
}



}

wingman87
18-04-2009, 13:12
E' corretto, però avresti potuto usare una variabile temporanea int invece di instanziare un nuovo oggetto solo per usarne un attributo.

australopiteci
18-04-2009, 14:51
E' corretto, però avresti potuto usare una variabile temporanea int invece di instanziare un nuovo oggetto solo per usarne un attributo.

si è vero..

thx 4 all

ciao :)