Метод клонирования предназначен для создания глубокой копии.Убедитесь, что вы понимаете разницу между глубокими и мелкими копиями.В вашем случае конструктор копирования может быть шаблоном, который вы хотите.Однако в некоторых случаях вы не можете использовать этот шаблон, например, потому что вы создаете подкласс класса X и у вас нет доступа к нужному вам конструктору X.Если X корректно переопределяет свой метод клонирования (при необходимости), вы можете сделать копию следующим образом:
class Y extends X implements Cloneable {
private SomeType field; // a field that needs copying in order to get a deep copy of a Y object
...
@Override
public Y clone() {
final Y clone;
try {
clone = (Y) super.clone();
}
catch (CloneNotSupportedException ex) {
throw new RuntimeException("superclass messed up", ex);
}
clone.field = this.field.clone();
return clone;
}
}
Обычно при переопределении метода клонирования:
- Сделатьболее конкретный тип возвращаемого значения
- Начните с вызова
super.clone()
- Не включайте предложение throws, если вы знаете, что
clone()
также будет работать для любого подкласса (слабость шаблона-клона; сделать класс finalесли возможно) - Оставьте только неизменяемые и примитивные поля, но клонируйте изменяемые поля объекта вручную после вызова
super.clone()
(еще одна слабость шаблона-клона, поскольку эти поля нельзя сделать окончательными)
clone()
метод Object
(который в конечном итоге вызывается, когда все суперклассы подчиняются контракту), делает поверхностную копию и заботится о правильном типе времени выполнения нового объекта.Обратите внимание, как конструктор не вызывается во всем процессе.
Если вы хотите иметь возможность вызывать clone()
в экземплярах, то реализуйте интерфейс Cloneable
и сделайте метод общедоступным.Если вы не хотите иметь возможность вызывать его в экземплярах, но хотите, чтобы подклассы могли вызывать их super.clone()
и получать то, что им нужно, тогда не реализуйте Cloneable
и сохраняйте метод protected
если ваш суперкласс еще не объявил его открытым.
Шаблон клона сложен и имеет много подводных камней.Будьте уверены, это то, что вам нужно.Рассмотрим конструкторы копирования или статический фабричный метод.