Доступ к clone() из java.lang.Object
Вот что я не могу понять.
В java.lang.Object
параметр clone()
определяется с помощью модификатора protected
. По определению, к которому он может обращаться по имени внутри собственного определения класса, по имени внутри любого производного от него класса и по имени в определении любого класса в одном пакете.
Здесь класс Sample
находится в другом пакете и, очевидно, он не может получить доступ к clone()
из класса Object
. Но поскольку Sample
выводится неявно из Object
, почему он не может получить к нему доступ? В определении не сказано, что он должен удовлетворять обоим условиям (внутри того же пакета И также быть подклассом).
public class Sample {
public Object foo() throws CloneNotSupportedException {
...
return someObject.clone();
}
}
Ответы
Ответ 1
В вашем случае метод clone()
не отображается, потому что вы не вызываете его из подкласса. Sample
происходит от Object
, поэтому он может получить доступ к собственному методу clone()
, но не к другим объектам.
Объект clone()
был разработан с несколькими ошибками. Поэтому использовать его не рекомендуется - это очень сложно сделать правильно:
- предполагается, что не каждый объект клонируется по умолчанию
- если вы переопределите
clone()
, сделав его общедоступным, он все равно будет терпеть неудачу, потому что каждый класс должен реализовать Cloneable
-
Cloneable
, однако, не определяет какие-либо методы, поэтому пользователи объектов не могут ссылаться на него как Cloneable
и ожидать метода клонирования.
- каждый класс в иерархии должен вызывать
super.clone()
для работы механизма клонирования по умолчанию
Отметьте этот вопрос для альтернатив.
Ответ 2
Работает для меня: http://ideone.com/eST8Y
import java.util.*;
import java.lang.*;
class Main
{
public Object foo() throws CloneNotSupportedException
{
return this.clone();
}
public static void main (String[] args) throws java.lang.Exception
{
new Main().foo();
}
}
Он компилируется без ошибок. Он по-прежнему запускает среду выполнения CloneNotSupportedException
, потому что Main
не реализует Cloneable
.
Класс реализует интерфейс Cloneable
, чтобы указать методу Object.clone()
, что законным для этого метода является создание экземпляров экземпляра этого класса для поля.
Вызов метода клонирования объекта в экземпляре, который не реализует интерфейс Cloneable
, приводит к тому, что исключение CloneNotSupportedException
выбрано.
@Bozho answer - это действительно правильный ответ. Просто не используйте Object.clone()
.
См. Эффективная Java, пункт 10: разумно переопределить clone
(пункт 11 в последующих выпусках).
Ответ 3
Здесь важен тип класса someObject
. Объект someObject
не может переопределять метод clone()
класса Object
, поэтому создание невидимо для класса Sample
.
Ответ 4
Что значит "не иметь доступа к нему"? Вы имеете в виду, что он не будет компилироваться или вы имеете в виду, что он вызывает исключение CloneNotSupportedException.
Object.clone()
будет бросать CloneNotSupportedException
, если ваш класс не реализует интерфейс Cloneable.