2016-09-05 4 views
1

Я знаю, что соглашение об имплантации Object#clone() говорит, что вы должны позвонить super.clone(), чтобы получить скопированный объект.На самом деле последствия Object.clone() не вызвали super.clone()?

Но мне просто интересно, каковы последствия, если я этого не сделаю. Итак, давайте предположим, этот пример:

class SomeClass implements Cloneable { 
    private Object someField; 

    public SomeClass(Object someField) { 
     this.someField = Object someField; 
    } 

    public Object clone() { 
     return new SomeClass(this.someField); 
    } 
} 

Я чувствую, что это не право (TM). Если мне нужен какой-либо конструктор копирования или метод копирования, я бы просто использовал это, а не Object#clone().

Однако, спотыкаясь об этом в некотором устаревшем коде, я просто задавался вопросом: это действительно опасно? Или просто creative, но на самом деле плохой стиль?

+0

Вы просто мелко копируете объект, а не глубоко копируете его. избыток someField будет влиять на оба объекта. –

+3

super.clone() также создает по умолчанию неглубокую копию, так что это не проблема –

ответ

1

Действительно ли это опасно? Или просто творческий, но на самом деле плохой стиль?

Опасность состоит в том, что SomeClass может быть подклассифицирован. Это означает, что подкласс также должен будет переопределить этот метод или он фактически не вернет экземпляр am того же типа.

Другая потенциальная проблема заключается в том, что дополнительное поле добавляется к SomeClass, но вы забываете обновить метод clone().

Если вы используете super.clone(), вам не придется беспокоиться об этих проблемах.

+0

Интересно, как вызов super.clone() предотвращает вторую проблему, о которой вы упомянули. Благодарю. – xxlali

+0

Хорошо, так что беспокойство было бы: на самом деле вы решаете против использования API клона Java, но вы * делаете его похожим на то, что вы это делаете *. И в итоге вы забудете обновить этот метод. С помощью экземпляра-копии или пользовательского метода копирования вы, вероятно, подумали бы об этом. +1 для аргумента подкласса, потому что это действительно нарушает клон-контракт. –

+1

@xxlali 'super.clone()' копирует все поля, а не только те, которые существовали в какой-то момент, когда вы написали метод. Добавьте поле, и вам не нужно забывать менять код еще где. –