Есть два популярных подхода. Один из них - предоставить метод clone, как вы упомянули, вот так.
public class C implements Cloneable {
@Override public C clone() {
try {
final C result = (C) super.clone();
// copy fields that need to be copied here!
return result;
} catch (final CloneNotSupportedException ex) {
throw new AssertionError();
}
}
Обратите внимание на "копировать поля... сюда!" часть. Первоначальный result является лишь поверхностной копией, а это означает, что если есть ссылка на объект, и оригинал, и result будут использовать один и тот же объект. Например, если C содержит private int[] data, вы, вероятно, захотите его скопировать.
...
final C result = (C) super.clone();
result.data = data.clone();
return result;
...
Обратите внимание, что вам не нужно копировать примитивные поля, так как их содержимое уже скопировано, или неизменяемые объекты, так как они все равно не могут измениться.
Второй подход заключается в предоставлении конструктора копирования.
public class C {
public C(final C c) {
// initialize this with c
}
}
Или копировальная фабрика.
public class C {
public static C newInstance(final C c) {
return new C(c);
}
private C(final C c) {
// initialize this with c
}
}
Оба подхода имеют свои свойства. clone хорош, потому что это метод, поэтому вам не нужно знать точный тип. В конце концов, вы всегда должны получать «идеальную» копию. Конструктор копирования удобен тем, что у вызывающей стороны есть шанс принять решение, как это видно из коллекций Java.
final List c = ...
// Got c from somewhere else, could be anything.
// Maybe too slow for what we're trying to do?
final List myC = new ArrayList(c);
// myC is an ArrayList, with known properties
Я рекомендую выбрать любой подход, который вам больше подходит.
Я бы использовал другие подходы, такие как рефлексивное копирование или немедленная сериализация/десериализация, только в модульных тестах. Мне они кажутся менее подходящими для производственного кода, в основном из-за проблем с производительностью.
person
Ronald Blaschke
schedule
24.01.2009