Frage

Effective Java, der Verfasser, dass:

Wenn eine Klasse implementiert klonbar, Objekt Klon-Methode gibt ein Feld-für-Feld-Kopie des Objekts; sonst wirft es CloneNotSupportedException.

Was ich möchte wissen, ist, was er bedeutet, mit Feld-für-Feld zu kopieren. Bedeutet es, dass, wenn die Klasse hat X in Speicher-Bytes, es wird nur das Stück Speicher kopieren? Wenn ja, dann gehe ich davon alle Werttypen der ursprünglichen Klasse werden auf das neue Objekt kopiert werden?

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

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

Wenn das, was Object.clone() tut, ist ein Feld für Feld Kopie der Point Klasse, würde ich sagen, dass ich nicht explizit brauchen würde, um Felder zu kopieren x und y, ist, dass der obige Code mehr gezeigt als genug, um ein machen Klon der Point Klasse. Das heißt, der folgende Code ist redundant:

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

rechts bin ich?

Ich weiß, Referenzen des geklonten Objekts zeigen automatisch an, wo das ursprüngliche Objekt Referenzen zeigten auf, ich bin nur nicht sicher, was speziell mit Werttypen geschieht. Wenn jemand könnte klar zum Ausdruck, was Object.clone() Algorithmus Spezifikation (in einfacher Sprache) ist, das groß sein würde.

War es hilfreich?

Lösung

Ja, ein Feld für Feld Kopie bedeutet, dass, wenn sie das neue (geklonte) Objekt erstellt, wird die JVM den Wert jeden Feld aus dem ursprünglichen Objekt in das geklonte Objekt kopieren. Leider bedeutet dies, dass Sie eine flache Kopie haben. Wenn Sie eine tiefe Kopie wünschen, können Sie die Klon-Methode überschreiben.

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;
    }
}

Auch eine weitere wichtige Sache, über das Klonen, wird der Konstruktor der geklonte Objekt nie aufgerufen (nur die Felder kopiert werden). Also, wenn der Konstruktor ein externes Objekt initialisiert, oder registriert diese Aufgabe mit einigen Registry, dann ist das nicht für das geklonte Objekt passieren.

Ich bevorzuge persönlich nicht Javas Klonen verwenden. Statt in der Regel ich meine eigene „Vervielfältigung“ Methoden erstellen.

Andere Tipps

Es bedeutet eine flache Kopie - die Felder kopiert werden, aber wenn Sie alle Verweise, was zu diesem Punkt nicht kopiert wird - Sie zwei Referenzen auf das gleiche Objekt haben wird, einen im alten Objekt und einen in dem neues, geklonte Objekt. Doch für die Felder, die primitiven Typen haben, ist das Feld die Daten selbst, so dass sie unabhängig kopiert werden.

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

Das ist richtig -. Diese sind redundant, da sie bereits durch Objekt clone () -Methode kopiert haben, werden

Denken Sie es als eine Datenkopie ist richtig. Primitive Typen werden kopiert und Referenzen werden ebenfalls kopiert, so dass sie auf das gleiche Objekt zeigen. Zum Beispiel:

class A implements Cloneable {
  Object someObject;
}

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

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

Die Standard-Klon führt flache Kopie von Werten. Für primitive Werte, das ist genug und keine zusätzliche Arbeit erforderlich ist.

Für Objekte, kopieren Sie die flachen Mittel nur die Referenz zu kopieren. Daher wird eine tiefe Kopie in diesen Fällen in der Regel erforderlich. Die Ausnahme hierfür ist, wenn der Verweis auf ein unveränderliches Objekt verweist. Unveränderliche Objekte können ihre scheinbare Zustand nicht geändert haben, deshalb können ihre Referenzen sicher kopiert herum. Zum Beispiel gilt dies für String, Integer, Float, Aufzählungen (wenn versehentlich nicht wandelbar gemacht).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top