Clone () vs Construtor de cópia, recomendado em java

clone method vs copy constructor em java. qual é a solução correta. onde usar cada caso?

Clone está quebrado, então não use.

O MÉTODO CLONE da class Object é um método mágico que faz o que nenhum método Java puro poderia fazer: ele produz uma cópia idêntica de seu object. Ele esteve presente na superclass de objects primordiais desde os dias de lançamento Beta do compilador Java *; e, como toda magia antiga, requer o encantamento apropriado para impedir que o feitiço comece inesperadamente.

Prefiro um método que copie o object

 Foo copyFoo (Foo foo){ Foo f = new Foo(); //for all properties in FOo f.set(foo.get()); return f; } 

Leia mais http://adtmag.com/articles/2000/01/18/effective-javaeffective-cloning.aspx

Tenha em mente que clone() não funciona fora da checkbox. Você terá que implementar Cloneable e replace o método clone() fazendo em public .

Existem algumas alternativas, que são preferíveis (uma vez que o método clone() tem muitos problemas de design, como indicado em outras respostas), e o construtor de cópia exigiria trabalho manual:

  • BeanUtils.cloneBean(original) cria um clone superficial, como o criado por Object.clone() . (esta class é de commons-beanutils )

  • SerializationUtils.clone(original) cria um clone profundo. (ou seja, todo o gráfico de propriedades é clonado, não apenas o primeiro nível) (do commons-lang ), mas todas as classs devem implementar Serializable

  • Java Deep Cloning Library oferece clonagem profunda sem a necessidade de implementar Serializable

clone () foi projetado com vários erros (veja essa questão ), então é melhor evitá-lo.

De Effective Java 2nd Edition , Item 11: Substituir clone judiciosamente

Dados todos os problemas associados ao Cloneable, é seguro dizer que outras interfaces não devem estendê-lo, e que classs projetadas para inheritance (Item 17) não devem implementá-lo. Por causa de suas muitas deficiências, alguns programadores especialistas simplesmente escolhem nunca replace o método clone e nunca invocá-lo, exceto, talvez, copiar matrizes. Se você projetar uma class para inheritance, esteja ciente de que, se você optar por não fornecer um método clone protegido bem comportado, será impossível que as subclasss implementem Cloneable.

Este livro também descreve as muitas vantagens que os construtores de cópia têm sobre Cloneable / clone.

  • Eles não dependem de um mecanismo de criação de objects extralinguísticos propenso ao risco
  • Eles não exigem adesão inexequível a convenções finamente documentadas
  • Eles não entram em conflito com o uso adequado dos campos finais
  • Eles não lançam exceções verificadas desnecessárias
  • Eles não exigem castings.

Todas as collections padrão possuem construtores de cópia. Usa-os.

 List original = // some list List copy = new ArrayList(original); 

Tenha em mente que o construtor de cópia limita o tipo de class ao do construtor de cópia. Considere o exemplo:

 // Need to clone person, which is type Person Person clone = new Person(person); 

Isso não funciona se a person puder ser uma subclass de Person (ou se Person for uma interface). Este é o ponto principal do clone, é que ele pode clonar o tipo apropriado dinamicamente em tempo de execução (supondo que o clone seja implementado corretamente).

 Person clone = (Person)person.clone(); 

ou

 Person clone = (Person)SomeCloneUtil.clone(person); // See Bozho's answer 

Agora a person pode ser qualquer tipo de Person supondo que o clone esteja implementado corretamente.

Veja também: Como replace corretamente o método clone? . A clonagem é quebrada em Java, é tão difícil acertar, e mesmo quando isso acontece, não oferece muito , então não vale a pena o incômodo.

Grande tristeza: nem Cloneable / clone nem um construtor são ótimas soluções: EU NÃO QUERO CONHECER A CLASSE DE IMPLEMENTAÇÃO !!! (por exemplo – eu tenho um mapa, que eu quero copiar, usando a mesma implementação oculta do MumbleMap) Eu só quero fazer uma cópia, se isso for suportado. Mas, infelizmente, Cloneable não tem o método clone nele, então não há nada para o qual você possa digitar com segurança em qual invocar clone ().

Seja qual for a melhor biblioteca de “object de cópia” existente, o Oracle deve torná-lo um componente padrão da próxima versão do Java (a menos que já esteja, oculto em algum lugar).

É claro que, se mais da biblioteca (por exemplo, collections) fosse imutável, essa tarefa de “cópia” simplesmente desapareceria. Mas então nós começaríamos a projetar programas Java com coisas como “invariantes de class” ao invés do padrão “bean” verdammt (fazer um object quebrado e mudar até bom [o suficiente]).