Cloneable в Java по своей сути нарушена. В частности, моя самая большая проблема с интерфейсом заключается в том, что он ожидает поведения метода, который не определяет сам метод. Поэтому, если вы переходите через список Cloneable, вы должны использовать отражение для доступа к его определенному поведению. Однако в Java 8 у нас теперь есть методы по умолчанию, и теперь я спрашиваю, почему в Cloneable нет метода clone() по умолчанию.
Я понимаю, почему интерфейсы не могут использовать методы Object по умолчанию, однако это было явное конструктивное решение, и поэтому могут быть сделаны исключения.
Я представляю себе невнимательность Object.clone() и меняю свой внутренний код на что-то вроде:
if(this instanceof Cloneable) {
return ((Cloneable) this).clone();
}
else {
throw new CloneNotSupportedException();
}
И перемещение по любой магии делает clone() делать свое дело как метод по умолчанию в Cloneable. Это на самом деле не означает, что clone() может быть легко реализовано неправильно, но это другое обсуждение само по себе.
Насколько я могу все еще это изменение будет полностью обратно совместимо:
- Классы, которые в настоящее время переопределяют
clone(), но не реализуютCloneable(ПОЧЕМУ?!), будут по-прежнему технически хорошими (даже если это невозможно, но это ничем не отличается от предыдущего). - Классы, которые в настоящее время переопределяют
clone(), но реализацияCloneableвсе равно будет работать одинаково при ее реализации. - Классы, которые в настоящее время не переопределяют
clone(), но реализовалоCloneable(ПОЧЕМУ?!) теперь следовать спецификации, даже если это не полностью функционально правильно. - Те, которые использовали отражение и ссылались на
Object.clone(), по-прежнему функционально работали. -
super.clone()будет по-прежнему функционально одинаковым, даже если он ссылается наObject.clone().
Не говоря уже о том, что это решит огромную проблему, которая есть Cloneable. Несмотря на то, что он утомительно и по-прежнему легко реализуется некорректно, он будет решать огромную объектно-ориентированную проблему с интерфейсом.
Единственная проблема, с которой я вижу, - это те, которые реализуют Cloneable не обязаны переопределять clone(), но это ничем не отличается от того, что было раньше.
Было ли это обсуждено внутренне, но так и не пришло в себя? Если да, то почему? Если по той причине, что интерфейсы не могут использовать методы Object по умолчанию, не имеет смысла делать исключение в этом случае, поскольку все объекты, наследующие Cloneable, ожидали clone() в любом случае?