PDA

View Full Version : [Java] Passare oggetti ad una funzione evitando che li modifichi


ka0s
20-06-2006, 11:51
In una classe ho scritto un metodo che prende come argomenti un paio di oggetti di tipo Stack.
Il metodo usa al suo interno funzioni tipo push() e pop(), quindi modifica gli oggetti.
Il problema è che quando si ritorna al programma "principale" (quindi quando finisce l'esecuzione del metodo) mi ritrovo con gli oggetti che gli avevo passato modificati... c'è invece un modo per far sì che al ritorno dal metodo gli oggetti che erano stati passati rimangano "così com'erano" ?

In altre parole ho bisogno di passare degli oggetti ad un metodo, il quale ci dovrà lavorare sopra (sarebbe comodo se potesse lavorare su una "copia indipendente") modificandoli ma al termine dell'esecuzione gli oggetti devono essere nello stato iniziale (cioè com'erano prima che glieli passassi come argomento).

Futuregames
20-06-2006, 12:38
edit ho sbagliato nn mi ricordo :D

PGI-Bis
20-06-2006, 13:00
Il modo più radicale è passare anzichè il riferimento all'oggetto un riferimento ad un suo clone profondo.

Per clone profondo di una pila intendo una pila diversa che contenga i cloni profondi degli oggetti contenuti nella pila originale.

Per quanto riguarda la produzione di un clone profondo di un oggetto occorre distinguere tra oggetti mutabili e oggetti immutabili.

Nel caso dei primi, devi produrre un oggetto che non possieda, direttamente o indirettamente, campi che facciano riferimento agli stesso oggetti.

Nel caso dei secondi il clone profondo non è necessario, essendo l'oggetto per sua natura non passibile di subire mutazioni di stato.

Ad esempio, il clone profondo di un oggetto di tipo:

class Name {
private String value;

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}
}

è una diversa istanza di Name che abbia come campo value un riferimento allo stesso oggetto String, perchè String è immutable:

public Name deepCloneName(Name n) {
Name n = new Name();
n.setValue(n.getValue());
return n;
}

Il clone profondo di una pila di Name sarebbe quindi:

//pseudo codice
public Stack<Name> deepCloneStack(Stack<Name> s) {
Stack<Name> clone = new Stack<Name>();
per ogni Name s in s, partendo dal fondo:
clone.push(deepCloneName(n));
return clone;
}

Al che passeresti come argomento del tuo metodo non la pila originale "stack" ma deepCloneStack(stack).

Puoi anche usare il metodo clone (sovrascrivendolo perchè è una clonazione superficiale) e in quel caso esprimi semanticamente la precondizione "profondo" nella documentazione del metodo anzichè nella sua firma.

Il vero problema è se esista uno strumento sintattico per esprimere la necessità che l'argomento sia un clone profondo.

M pare che una soluzione sia obbligare l'oggetto ad essere un JavaBean, eventualmente composto di soli JavaBean. Ma bisognerebbe indagare.

andbin
20-06-2006, 13:05
Si può clonare un oggetto:
Stack s = new Stack ();

....

Stack s2 = (Stack) s.clone ();
EDIT: Credo che PGI-Bis abbia spiegato meglio.

ka0s
20-06-2006, 16:06
Grazie!! Proverò con questo modo anche se mi sembra piuttosto avanzata come cosa! ;)