Создание функции клонирования без исключения CloneNotSupportedException в Java - PullRequest
3 голосов
/ 23 декабря 2011

В рамках нашей домашней работы нам предлагается реализовать абстрактный класс с помощью метода clone. Рамка для функции дана:

/**
 * @effects Creates and returns a copy of this.
 */
public Object clone() {
    // TODO: Implement this method


}

Класс Shape имеет два поля:

private Point location;
private Color color;

В инструкциях нам говорят, что метод не генерирует исключение CloneNotSupportedException, а также спрашивают, почему это так. Во всех примерах, которые мы видели в интернете, метод клонирования выдает CloneNotSupportedException.

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

Метод, который мы написали:

/**
 * @effects Creates and returns a copy of this.
 */

public Object clone() {
    Shape new_shape = (Shape)super.clone();
    new_shape.setColor(this.getColor());
    new_shape.location = (Point)location.clone();
    return new_shape;


}

Это дает нам ошибку со стороны (Shape)super.clone(), говоря:

Unhandled exception type CloneNotSupportedException, как мы должны создать метод клонирования?

Ответы [ 3 ]

8 голосов
/ 23 декабря 2011

Ваш класс должен реализовывать Clonable интерфейс.

Также вы можете использовать Ковариантные типы возврата , чтобы возвращать Shape / Point вместо Object.Это поможет вам избежать ненужных приведений типов.

7 голосов
/ 23 декабря 2011

Необработанный тип исключения CloneNotSupportedException

Это потому, что метод clone() в Object определен как бросающий CloneNotSupportedException:

protected Object clone() throws CloneNotSupportedException

См. Документ API: Object#clone()

Чтобы преодолеть это, вам нужно либо обработать его с помощью блока try/catch, либо переопределить его, добавив предложение throws.

Обновление:

В инструкциях нам говорят, что метод не генерирует исключение CloneNotSupportedException, а также спрашивают, почему это так.

ИМО -

  1. Вы переопределяете метод в суперклассе. Только возвращаемый тип, имя метода и типы параметров считаются сигнатурой метода. Поэтому, переопределяя метод, вы можете опустить предложение throws в подклассе, даже если метод в суперклассе имеет его.
  2. Всякий раз, когда ваш класс реализует интерфейс Cloneable, он говорит классу Object, что можно создать его клон. В таком случае правильная реализация метода clone должна вызывать метод super.clone. Теперь вы можете видеть, что на самом деле метод clone в классе Object делает копию. Итак, мы должны оставить до Object.clone(), чтобы бросить это CloneNotSupportedException. И это будет сделано, если какой-либо класс в иерархии не реализует интерфейс Cloneable.

Надеюсь, это имеет смысл.

Даже если он довольно обширный, на случай, если вы захотите прочитать об этом больше. Это объясняется в Эффективной Java - пункт 10: разумное переопределение клона .

2 голосов
/ 23 декабря 2011

Причина, по которой другие реализации генерируют исключение CloneNotSupportedException, заключается в том, что он является частью существующего метода clone () объекта . Тот факт, что метод определен как исключение, не означает, что он должен это делать. При реализации вашего метода clone () в Shape и его производных классах не создавайте исключение.

Причина, по которой (Shape)super.clone() вызывает исключение, заключается в том, что это поведение по умолчанию. Реализуйте clone () в Shape.

...