Если у вас есть такая структура:
class Y {}
class X extends Y implements Cloneable {
@Override
public X clone() {
try {
return (X) super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError(e);
}
}
}
Тогда клон на экземплярах X
будет работать нормально. Он не будет работать на прямых экземплярах Y
, потому что они не объявлены клонируемыми. Но интерфейс Cloneable
в X
является индикатором механизмов реализации по умолчанию clone()
, что их следует заставить работать.
В качестве альтернативы
Вы также можете иметь неклонируемый класс с рабочим методом clone()
, если вы не полагаетесь на реализацию по умолчанию clone()
.
Например:
class Y {
@Override
public Y clone() {
// Don't call super.clone() because it will error
return new Y(...); // whatever parameters
}
}
Однако, с помощью этого механизма, если вы вызываете super.clone()
из подкласса Y
, вы получите экземпляр Y
, что, вероятно, не то, что вы хотели бы.
Как уже отмечали другие, механизм Cloneable
неудобен и запутан, и обычно с механизмами копирования, использующими new
, работать легче.