Pessoal,
Existe alguma forma de Criarmos uma cópia de um Objeto sem compartilhamento de memória?. Ex: Obj1 = Obj2, mas cada objeto está alocado em uma posição.
Estou desenvolvendo um mecanismo de “Log” das operações de CRUD para minha aplicação, nesse mecanismo tenho um método que
após efetuada uma alteração no BD é invocado passando dois parâmetros “Objeto antes da alteração” e “Objeto após alteração”,
a partir de então ele irá realizar a comparação nos valores do objeto e gravar em um BD de Log algumas informações
como: qual campo foi alterado, qual é o valor antigo do campo, usuário que alterou etc… Esse mecanismo está sendo invocado nos métodos de CRUD do DAO.
Até ai tudo bem !!!
Meu problema está na preparação desses objetos que tenho que passar como parâmetro,
Pois mesmo realizando um select no BD para obter o Objeto antes da alteração a JVM cria um ponteiro para o Objeto que já está na memória
(ficando os dois Objetos com o mesmo conteúdo).
public void altera(Pessoa objAlterado) {
// Select para Obter o Objeto antes da alteração,
// como a alteração ainda não foi comitada no BD ainda consta o Obj antigo
// mas nesse momento o valor que recebo no Obj é o valor alterado pois a JVM
// criou um ponteiro dizendo que os objetos são os mesmos.
Pessoa objAntes = this.buscaPorId(objAlterado.getPessoaPK());
// executando a Alteração no Banco
dao.altera(objAlterado);
// Instanciando o Mecanismo de LOG
AuditTrail trail = new AuditTrail(em);
// Executando a comparação
trail.updated(objAlterado, objAlterado);
}
Obrigado…
Você pode clonar o objeto.
[code]public class Cliente implements Cloneable {
private String nome;
// outros campos...
// gets e sets
@Override
public Object clone() {
// cria uma nova instância da classe
Cliente c = new Cliente();
// copia os campos
c.setNome( this.nome );
// outros campos aqui...
return c;
}
}
// usando…
Cliente c = new Cliente();
c.setNome( “João” );
Cliente cc = (Cliente) c.clone();[/code]
Algo que você tem que tomar cuidado é de fazer cópias defensivas dos atributos do objeto que está sendo clonado caso seja necessário.
Para classes imutáveis (como String) e primitivos e seus wrappers (int, Integer, long, Long, etc.) (wrappers são imutáveis) você pode atribuir diretamente o valor como eu fiz, mas para classes mutáveis como um Calendar por exemplo, ai sim você precisa fazer uam cópia do objeto que será o valor atribuído ao clone, pois caso o objeto original seja alterado no objeto não clonado, o valor contido no objeto clonado será modificado também. Essa cópia pode ser feita usando o método clone caso a classe o suporte ou então clonando manualmente.
[]'s
Ah, faltou dizer. Leia a documentação da interface Cloenable e do método clone da classe Object para saber qual é o contrato que deve ser seguido para a implementação do método clone. Eu omiti no exemplo o método equals que deve ser implementado para classes de valor como a do exemplo. Outro detalhe é que a interface Cloneable é só uma interface de marcação (assim como Serializable), sendo que o método clone é definido na classe Object. Os “porquês” disso estão descritos na documentação.
Cloneable: http://docs.oracle.com/javase/7/docs/api/java/lang/Cloneable.html
Object.clone(): http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#clone()
[]'s
Obrigado David,
Funcionou… Vou dar uma olhada na documentação também.
Valeu.