Domanda

In Effective Java, l'autore afferma che:

  

Se un implementa classe Cloneable,   metodo clone di Object restituisce un   campo per campo copia dell'oggetto;   altrimenti si getta   CloneNotSupportedException.

Quello che mi piacerebbe sapere è cosa intende con copia campo per campo. Vuol dire che se la classe ha X byte in memoria, sarà solo copiare quel pezzo di memoria? Se sì, allora posso assumere tutti i tipi di valore della classe originale verranno copiati al nuovo oggetto?

class Point implements Cloneable{
    private int x;
    private int y;

    @Override
    public Point clone() {
        return (Point)super.clone();
    }
}

Se Object.clone() fa è un campo da campo copia della classe Point, direi che non avrei bisogno di copiare i campi in modo esplicito x e y, essendo che il codice mostrato sopra sarà più che sufficiente per fare un clone della classe Point. Cioè, il seguente pezzo di codice è ridondante:

@Override
public Point clone() {
    Point newObj = (Point)super.clone();
    newObj.x = this.x; //redundant
    newObj.y = this.y; //redundant
}

ho ragione?

Lo so riferimenti dell'oggetto clonato punterà automaticamente al punto in cui i riferimenti dell'oggetto originale indicavano, solo che non sono sicuro di quello che accade in particolare con i tipi di valore. Se qualcuno potrebbe affermare chiaramente ciò che specifica l'algoritmo di Object.clone() è (in semplice linguaggio) sarebbe fantastico.

È stato utile?

Soluzione

Sì, un campo da copia campo vuol dire che quando si crea il nuovo oggetto (clonato), la JVM copierà il valore di ogni campo dall'oggetto originale nello oggetto clonato. Purtroppo questo significa che si dispone di una copia. Se si desidera una copia completa, è possibile ignorare il metodo clone.

class Line implements Cloneable {

    private Point start;
    private Point end;

    public Line() {
        //Careful: This will not happen for the cloned object
        SomeGlobalRegistry.register(this);
    }

    @Override
    public Line clone() {
        //calling super.clone is going to create a shallow copy.
        //If we want a deep copy, we must clone or instantiate
        //the fields ourselves
        Line line = (Line)super.clone();
        //assuming Point is cloneable. Otherwise we will
        //have to instantiate and populate it's fields manually
        line.start = this.start.clone();
        line.end = this.end.clone;
        return line;
    }
}

Anche una cosa più importante circa la clonazione è, il costruttore dell'oggetto clonato non è mai invocato (solo i campi vengono copiati). Quindi, se il costruttore inizializza un oggetto esterno, o registra questo oggetto con qualche registro, quindi che non accadrà per l'oggetto clonato.

Io personalmente preferisco non usare la clonazione di Java. Invece genere creo i miei metodi "duplicazione".

Altri suggerimenti

Ciò significa una copia - i campi vengono copiati, ma se avete dei riferimenti, ciò che questi punti di non viene copiato - si avranno due riferimenti allo stesso oggetto, uno nel vecchio oggetto e uno in nuovo, oggetto clonato. Tuttavia, per i campi che hanno i tipi primitivi, il campo è dati stessi, in modo da ottenere copiati indipendentemente.

newObj.x = this.x; //redundant
newObj.y = this.y; //redundant

che è di destra -. Questi sono ridondanti, dal momento che sono già stati copiati da clone di Object () Metodo

Pensare di esso come una copia dei dati è corretta. I tipi primitivi vengono copiati e riferimenti sono copiati in modo che puntano allo stesso oggetto. Ad esempio,

class A implements Cloneable {
  Object someObject;
}

A a = new A();
a.someObject = new Object();

A cloneA = (A)a.clone();
assert a.someObject==cloneA.someObject;

Il clone esegue di default copia superficiale di valori. Per i valori primitivi, questo è sufficiente e non è necessario alcun lavoro supplementare.

Per gli oggetti, la copia superficiale mezzi copiando solo il riferimento. Pertanto, in questi casi è di solito necessario una copia profonda. L'eccezione di questo è quando il riferimento punta a un oggetto immutabile. oggetti immutabili non possono avere il loro stato apparente è cambiato, quindi i loro riferimenti possono essere copiati in sicurezza. Ad esempio, questo vale per stringa, intero Float, enumerazioni (se non fatto mutabili per errore).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top