Доступ к clone () из java.lang.Object - PullRequest
       38

Доступ к clone () из java.lang.Object

4 голосов
/ 23 февраля 2011

Вот кое-что, что я не могу понять.

В java.lang.Object clone() определяется с модификатором protected.По определению, к нему можно получить доступ по имени внутри определения своего собственного класса, по имени внутри любого класса, производного от него, и по имени в определении любого класса в том же пакете.

Здесь класс Sampleнаходится в другом пакете, и, очевидно, он не может получить доступ к clone() из класса Object.Но поскольку Sample неявно вытекает из Object, почему он не может получить к нему доступ?В определении не сказано, что оно ДОЛЖНО удовлетворять обоим условиям (внутри одного пакета И также быть подклассом).

public class Sample {

  public Object foo() throws CloneNotSupportedException {
   ... 
   return someObject.clone();
  }
}

Ответы [ 4 ]

9 голосов
/ 23 февраля 2011

В вашем случае метод clone() невидим, потому что вы не вызываете его из подкласса. Sample происходит от Object, поэтому он может обращаться к своему собственному clone() методу, но не к другим объектам.

Объект clone() был разработан с несколькими ошибками. Так что не рекомендуется использовать его - очень трудно понять это правильно:

  • Предполагается, что не каждый объект является клонируемым по умолчанию
  • если вы переопределите clone(), сделав его общедоступным, он все равно потерпит неудачу, потому что каждый класс должен реализовать Cloneable
  • Cloneable, однако, не определяет какие-либо методы, поэтому пользователи объектов не могут ссылаться на него как Cloneable и ожидать клонирования.
  • каждый класс в иерархии должен вызывать super.clone(), чтобы механизм клонирования по умолчанию работал

Проверьте этот вопрос для альтернатив.

3 голосов
/ 23 февраля 2011

у меня работает: 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(), что для этого метода допустимо делать копию экземпляров этого класса в виде поля для поля.

При вызове метода клона Object в экземпляре, который не реализует интерфейс Cloneable, возникает исключение CloneNotSupportedException.


@ Ответ Божо здесь действительно правильный ответ. Только не используйте Object.clone().

См. Эффективная Java , пункт 10: разумно переопределить clone (пункт 11 в более поздних выпусках).

0 голосов
/ 23 февраля 2011

Что вы имеете в виду "не в состоянии получить к нему доступ"? Вы имеете в виду, что он не будет компилироваться, или вы имеете в виду, что он вызывает исключение CloneNotSupportedException.

Object.clone() выдаст CloneNotSupportedException, если ваш класс не реализует интерфейс Cloneable.

0 голосов
/ 23 февраля 2011

Здесь важен тип класса someObject. Объект someObject может не перекрывать метод clone() класса Object, поэтому создание невидимо для класса Sample.

...