Клонируемое поведение - PullRequest
       0

Клонируемое поведение

2 голосов
/ 13 августа 2010

Документ Java говорит -

Класс Object сам по себе не реализует интерфейс Cloneable, поэтому вызов метода clone для объекта, класс которого Object, приведет к возникновению исключения во время выполнения.

Почему метод клона в классе Object защищен?это так?

Это означает, что любой класс, который не реализует cloneable, будет вызывать исключение CloneNotSupported при вызове его метода clone.

Я запустил тестовую программу

public class Test extends ABC implements Cloneable{

    @Override
    public Object clone() throws CloneNotSupportedException {
        System.out.println("calling super.clone");
            return super.clone();
    }

    public static void main(String[] args) {
        Test t = new Test();
        try{
        t.clone();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class ABC{

}

Из клона метода Class Test вызывается super.clone?

Почему он не выдает исключение?

Ответы [ 6 ]

2 голосов
/ 13 августа 2010

Дерево наследования экземпляра Test t выглядит так:

Object
  ABC
    Test

Test также реализует Cloneable, что означает, что при вызове метода super.clone() Object s clone метод будет вызван.Он проверяет, реализует ли экземпляр t интерфейс Cloneable.Поскольку он реализует метод, не генерирует исключение.

1 голос
/ 13 августа 2010

Я бы сказал хороший вопрос, чтобы сбить с толку интервьюируемых:).

Что касается причины, по которой это не исключение.Думайте об этом объектным способом.Ваш объект t имеет класс Test, который реализует клонируемый.Когда вы вызываете метод super.clone, он все еще является объектом класса Test, и поэтому нет никаких причин для того, чтобы он вызывал исключение CloneNotSupported.Если бы это был объект класса Object, он бы выдал исключение.

1 голос
/ 13 августа 2010

Это может дать вам ответ на вопрос, почему метод защищен почему защищен метод клонирования

Это не вызывает исключение, потому что вы реализуете Cloneable. Из клонируемой документации:

"Класс реализует интерфейс Cloneable, чтобы указать методу Object.clone (), что для этого метода допустимо делать копию поля для поля экземпляров этого класса. Вызов метода клона Object в экземпляре, который не реализует интерфейс Cloneable, приводит к исключению CloneNotSupportedException. «

Но когда вы его реализуете, вы говорите реализации Object, что законно делать копию поля для поля, чтобы она не вызывала исключение.

1 голос
/ 13 августа 2010

Почему метод клонирования в классе Object protected?

Так что класс, который выбирает поддержку клонирования, не заставляет выставлять его в своем публичном API.

Как показывает ваш пример, подкласс может переопределять метод с более широким доступом, чем унаследованная версия метода. Вы просто не можете уменьшить доступ к методу таким образом.

Это означает, что любой класс, который не реализует cloneable, будет вызывать исключение CloneNotSupported при вызове его метода clone.

Это правильно.

Из клона метода Class Test вызывается super.clone?

Это правильно.

Почему не выдается исключение?

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

1 голос
/ 13 августа 2010

Потому что ваш класс реализует Cloneable. Из Javadoc из Cloneable:

Класс реализует интерфейс Cloneable, чтобы указать методу Object.clone (), что для этого метода допустимо делать копию поля для экземпляров этого класса в полевых условиях.

Так что это позволяет использовать метод Object clone(). Это (опять же в соответствии с Javadoc) просто соглашение об отмене clone(). Если вы не переопределите его, а метод Object clone() выполняет копирование поля для поля, вы все равно можете получить CloneNotSupportedException, если одно из полей само не является клонируемым. Поэтому рекомендуется переопределить его.

1 голос
/ 13 августа 2010

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

Из Javadoc:

Класс реализует интерфейс Cloneable, чтобы указать методу Object.clone (), что для этого метода допустимо делать копию поля для поля экземпляров этого класса.

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

См .: Клонируемый (Java Platform SE 6)

...