[resolvido] Clonar Objeto

Pessoal,

Sei que já fizeram essa pergunta muitas vezes, mas realmente não estou conseguindo.

Quero simplesmente copiar um objeto para outro, o problema é que esse objeto é complexo, ou seja contém Listas, Objetos de Objetos…, etc…

Tentei Clonable e BeanUtils do apache… (cloneBean e copyProperties)

Enfim, alguém já precisou fazer um clone deses?

Obrigado

cria um objeto e tenta copiar ele, faça o teste…

Object o = new Object();
o = carro;

if(o.equals(carro)) {
   System.out.println("OK");
}

if(o == carro) {
   System.out.println("OK");
}

[quote=lucasportela]cria um objeto e tenta copiar ele, faça o teste…

[code]
Object o = new Object();
o = carro;

if(o.equals(carro)) {
System.out.println(“OK”);
}

if(o == carro) {
System.out.println(“OK”);
}
[/code][/quote]

O que eu to dizendo é que em java é copiado somente a referencia e nao o objeto. E eu já sei disso.

Cara, você pode implementar a interface Cloneable da seguinte forma:

[code]public class TesteClone implements Cloneable{
int a;
public TesteClone(){}//Construtor normal
public TesteClone(TesteClone outro){//Contrutor de clonagem
this. a = outro.a;
}

 public Object clone(){
      return new(this);
 }

}[/code]

O clone normalmente é implementado através de um contrutor de clonagem.
Tente fazer dessa forma.

Cara, implementa Cloneable…

A forma como o matheuslmota indicou é boa, o chato é ficar clonando tudo o que precisar “na mão”.

Um jeito fácil e rápido que já fiz é no método clone() você deserializar o objeto e serializar novamente (assim além de Cloneable sua classe e todas as outras classes que ela tem atributos tem que implementar Serializable).

Já passei por um problema desses uma vez, a solução é simples, se vc deseja clonar um objeto implemente a interface Cloneable e sobrescreva seu metodo assim:

public class Modelo implements Cloneable {

        //Sobreescreva o metodo clone.
        public Modelo clone(){
                return (Modelo) super.clone();
         }

Agora se o seu caso é clonar uma estrutura Collection completa, será necessário pesquisar bem qual estrutura já possui o método clone() implementado, por exemplo:

List<Modelo> lista = new ArrayList<Modelo>(); // Essa instância de ArrayList não vem com o método clone() nativo.

ArrayList<Modelo> lista = new ArrayList<Modelo>(); // Já essa instância pura de ArrayList já vem com o método clone().

a princípio só conheço essa Collection (ArrayList pura) que possui técnicas de clonagem, as outras estruturas não sei ainda, pois nunca precisei usá-las para clonagem :lol:

[quote=Guilherme Trovo]Cara, implementa Cloneable…

A forma como o matheuslmota indicou é boa, o chato é ficar clonando tudo o que precisar “na mão”.

Um jeito fácil e rápido que já fiz é no método clone() você deserializar o objeto e serializar novamente (assim além de Cloneable sua classe e todas as outras classes que ela tem atributos tem que implementar Serializable).[/quote]

É disso que eu to falando!!! Ótima dica, só nao tenho ideia de como fazer. =p
Mas voce entendeu quando eu disse um objeto complexo. Obrigado

Se puder me dar um exemplo seria perfeito.

[quote=cafezin][quote=Guilherme Trovo]Cara, implementa Cloneable…

A forma como o matheuslmota indicou é boa, o chato é ficar clonando tudo o que precisar “na mão”.

Um jeito fácil e rápido que já fiz é no método clone() você deserializar o objeto e serializar novamente (assim além de Cloneable sua classe e todas as outras classes que ela tem atributos tem que implementar Serializable).[/quote]

É disso que eu to falando!!! Ótima dica, só nao tenho ideia de como fazer. =p
Mas voce entendeu quando eu disse um objeto complexo. Obrigado

Se puder me dar um exemplo seria perfeito.[/quote]

Você pode implementar seu método clone da seguinte forma:

public Object clone() { Object object = null; try { FileOutputStream fileOutputStream = new FileOutputStream("object.dat"); ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); objectOutputStream.writeObject(this); fileOutputStream.flush(); fileOutputStream.close(); objectOutputStream.flush(); objectOutputStream.close(); FileInputStream fileInputStream = new FileInputStream("object.dat"); ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); object = objectInputStream.readObject(); fileInputStream.close(); objectInputStream.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return object; }

Faça os devidos tratamentos nas clausulas catch. O código que mandei funciona da maneira que você quer, basta que a classe a ser clonada implemente Cloneable e Serializable, se não o código não roda.
Até mais

[quote=matheuslmota][quote=cafezin][quote=Guilherme Trovo]Cara, implementa Cloneable…

A forma como o matheuslmota indicou é boa, o chato é ficar clonando tudo o que precisar “na mão”.

Um jeito fácil e rápido que já fiz é no método clone() você deserializar o objeto e serializar novamente (assim além de Cloneable sua classe e todas as outras classes que ela tem atributos tem que implementar Serializable).[/quote]

É disso que eu to falando!!! Ótima dica, só nao tenho ideia de como fazer. =p
Mas voce entendeu quando eu disse um objeto complexo. Obrigado

Se puder me dar um exemplo seria perfeito.[/quote]

Você pode implementar seu método clone da seguinte forma:

public Object clone() { Object object = null; try { FileOutputStream fileOutputStream = new FileOutputStream("object.dat"); ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); objectOutputStream.writeObject(this); fileOutputStream.flush(); fileOutputStream.close(); objectOutputStream.flush(); objectOutputStream.close(); FileInputStream fileInputStream = new FileInputStream("object.dat"); ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); object = objectInputStream.readObject(); fileInputStream.close(); objectInputStream.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return object; }

Faça os devidos tratamentos nas clausulas catch. O código que mandei funciona da maneira que você quer, basta que a classe a ser clonada implemente Cloneable e Serializable, se não o código não roda.
Até mais[/quote]

Amigo, o que eu vou te falar?
Simplesmente show de bola! Funcionou como esperado

Grande Abraço e obrigado.

o jeito que o matheuslmota postou é bom, só vejo talvez um problema de concorrência com o file object.dat…
procurando no google por “java clone serializable” ou “java deep copy” você acha vários exemplos, segue um que encontrei aqui que utiliza serialização sem utilizar file.

Object cloneSerializable(Serializable obj) {
  ObjectOutputStream out = null;
  ObjectInputStream in = null;
 
  try {
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    out = new ObjectOutputStream(bout);
			
    out.writeObject(obj);
    out.close();
			
    ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
    in = new ObjectInputStream(bin);			
    Object copy = in.readObject();
 
    in.close();
			
    return copy;
  } catch (Exception ex) {
    ex.printStackTrace();
  } finally {
    try {
      if(out != null) {
        out.close();
      }
				
      if(in != null) {
        in.close();
      }
    } catch (IOException ignore) {}
  }
		
  return null;
}

[quote=Guilherme Trovo]o jeito que o matheuslmota postou é bom, só vejo talvez um problema de concorrência com o file object.dat…
procurando no google por “java clone serializable” ou “java deep copy” você acha vários exemplos, segue um que encontrei aqui que utiliza serialização sem utilizar file.

[code]
Object cloneSerializable(Serializable obj) {
ObjectOutputStream out = null;
ObjectInputStream in = null;

try {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
out = new ObjectOutputStream(bout);

out.writeObject(obj);
out.close();
		
ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
in = new ObjectInputStream(bin);			
Object copy = in.readObject();

in.close();
		
return copy;

} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
if(out != null) {
out.close();
}

  if(in != null) {
    in.close();
  }
} catch (IOException ignore) {}

}

return null;
}
[/code][/quote]

Interessante essa solução. Quando publiquei o código eu tentei fazer algo parecido com isso, sem usar arquivos, mas não havia conseguido.

Eu tinha tentando isso aqui… mas deu muitos problemas
http://code.google.com/p/cloning/

Por enquanto vou ficar com a solução do matheuslmota que ja esta funcionando, depois vou testar esta outra. Muito obrigado

Cara, edita seu primeiro post e acrescenta [Resolvido] ao título.
Abraço.

Oi pessoal, e quando a classe que eu quero clonar não implementa Serializable?

Não pode. A classe deve implementar Serializable.

Pois então, essa maneira que foi descrita é justamente usando serialização, tanto em memória quanto em arquivo. Existem outras soluções mais simples para clonar, são as que foram descritas nas primeiras respostas deste post.