Cloneable
в Java по своей сути не работает. В частности, моя самая большая проблема с интерфейсом заключается в том, что он ожидает поведения метода, который не определяет сам метод. Поэтому, если вы переходите через список Cloneable
, вы должны использовать отражение для доступа к его определенному поведению. Однако в Java 8 у нас теперь есть методы по умолчанию, и теперь я спрашиваю, почему в Cloneable
нет метода clone()
по умолчанию.Почему по умолчанию clone() в Cloneable в Java 8
Я понимаю, почему interfaces cannot default Object methods, однако это было явное дизайнерское решение, и поэтому могут быть сделаны исключения.
Я сортирую себе протестующий 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()
в любом случае?
Я помню, где-то читал (из официальных источников), что «Cloneable» был настолько сломан, что даже не стоило исправлять. Но одна из проблем с вашим методом по умолчанию заключается в том, что использование 'this' здесь сложно. – Tunaki
По сути, то, что говорит @Tunaki, является правильным. Невозможность возврата на сложность такого рода обручей не была; мы решили инвестировать наши бюджеты {время, усилие, сложность) в другие области, которые принесли большую ценность. –
Нет смысла создавать такой метод 'default'. Если в 'java.lang.Object' и методе' default' есть один и тот же имя и подпись в «интерфейсе» есть метод, метод, объявленный в 'java.lang.Object', по-прежнему выигрывает за неквалифицированные вызовы. И если метод в java.lang.Object' остается «защищенным», все реализации «Cloneable» применяются для повторного использования метода как «public», а при изменении его на «public» все равно потребуется адаптировать существующие реализации. Другими словами, результат не отличается от определения метода 'abstract clone()' в интерфейсе 'Cloneable'. – Holger