2013-05-01 5 views
2

Я прочитал много потоков о методе clone() объекта и Cloneable Interface, но я не смог найти законный ответ на мой вопрос. Короче говоря:Почему не следует клонировать объект?

Что я понял, так это то, что Object имеет метод clone(), который может «магически» клонировать ваш объект. Но вы не можете использовать этот метод без реализации Cloneable Interface, потому что этот интерфейс позволяет Object использовать метод clone(). Так почему они это сделали? Почему каждый объект не должен быть клонимым с самого начала?

+1

Открытые вопросы, такие как 'Почему foo реализован таким образом? ', Без четкого ответа, не подходят для StackOverflow. См. [FAQ]. – Keppil

+0

Вы сделали свою [* домашнюю работу *] (http://stackoverflow.com/questions/4081858/about-java-cloneable)? –

ответ

3

Cloneable имеет смысл для некоторых изменяемых данных.

Это не имеет смысла для

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

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

Примечание: Есть много проектов, которые не позволяют использовать Cloneable в любом месте.

+0

, который мне очень помог, большое спасибо – user2338815

+0

Нет ничего плохого в том, что «clone» на неизменяемом объекте может просто вернуть тот же объект.Единственная фундаментальная проблема (но она большая) с клонированием возникает, если объект инкапсулирует как изменяемое состояние какого-либо объекта или объекта, так и инкапсулирует личность этого объекта. При клонировании одного объекта, клон может инкапсулировать либо отдельную копию состояния оригинала, либо сохранить идентификатор объекта, используемого для инкапсуляции исходного состояния, но не для обоих. – supercat

+0

Если бы существовало соглашение о том, что неизменяемые типы должны реализовывать 'clone' как просто' return this', тогда имеет смысл иметь отдельные типы для наборов значений (значения должны реализовывать «cloneable») и набор ссылок (ссылки методы клонирования не будут использоваться). Чтобы действительно сделать эту работу, должен существовать «cloneableObject» с защищенным «магическим» методом 'memberwiseClone', который всегда работал бы, в отличие от наличия метода« clone »в объекте, который может работать или не работать; поддержка общедоступного метода клонирования не зависит от вывода из 'cloneableObject'. – supercat

-2

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

Пример

  MyObject obj1 = new MyObject(); 
     obj2 = obj1; 

Здесь, в этом случае любые изменения, внесенные в obj1 будут отражать в obj2 и наоборот, потому что obj2 имеет место памяти obj1.

, но если вы не хотите, изменение в obj2 должно быть видно в obj1, или любое изменение, сделанное в obj1, будет видно в obj2, тогда вы выполните Cloning. В этом случае оба объекта будут иметь разную память.

1

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

class MyClass 
{ 
    private int val; 
    public void setVal(int i) 
    { 
    this.val = i; 
    } 
    public int getVal() 
    { 
    return this.val; 
    } 
    public static void main(String st[]) throws Exception 
    { 
    ArrayList<MyClass> ar = new ArrayList<MyClass>(); 
    MyClass mc = new MyClass(); 
    mc.setVal(50); 
    ar.add(mc); 
    ArrayList<MyClass> copy =(ArrayList) ar.clone();//Since ArrayList is cloneable 
    copy.get(0).setVal(10); 
    System.out.print(ar.get(0).getVal());//it shows 10 instead of 50!! 
    } 
} 

Таким образом, мы видим, что клонирование может привести к несогласованности в внутреннее состояние исходного объекта копируются. Поэтому, чтобы избежать такого сценария, распространенность предоставляется программисту при определении класса, хочет ли он, чтобы объект этого класса был клонирован или нет.

+0

спасибо за яркий пример :) – user2338815

Смежные вопросы