Skip to content
abril 13, 2007 / cassiomarques

Nem tudo é o que parece ser: Como eu descobri (da pior forma) que deve-se evitar o uso do método clone() em Java

Estava eu aqui feliz da vida programando quando precisei criar uma cópia idêntica de um objeto. Pensei: “Ah, existe aquele método bacana, clone(). Nunca usei, mas deve ser simples!”.

Resultado: Me ferrei. Realmente nem tudo é o que parece ser. O que eu imaginei é que esse método de alguma forma serializasse o objeto em memória, alocasse n bytes em outro endereço e fizesse flush dos bytes serializados dentro da área recém-alocada. Voilá, tenho uma cópia e um referência para a mesma! Ah, se tudo fosse tão bonito…

Veja abaixo um exemplo de porque clone() não funciona como qualquer desavisado imaginaria: (atencão puristas OO, isso é apenas um exemplo!):

public class CloneDaProblema{
public static void main(String[] args){
int[][] matrizOriginal = new int[2][2];

for(int i = 0; i < 2; i++) for(int j = 0; j < 2; j++) matrizOriginal[i][j] = i + j; int[][] matrizClonada = matrizOriginal.clone(); System.out.println("Conteudo da matriz original:"); imprime(matrizOriginal); System.out.println("Conteudo da matriz clonada:"); imprime(matrizClonada); System.out.println("nAlterando valor do elemento [0][0]..."); matrizClonada[0][0] = 3; System.out.println("nConteudo da matriz original:"); imprime(matrizOriginal); System.out.println("Conteudo da matriz clonada:"); imprime(matrizClonada); } public static void imprime(int[][] m){ for(int i = 0; i < m.length; i++){ for(int j = 0; j < m[0].length; j++) System.out.print(m[i][j] + " "); System.out.println(); } } } [/sourcecode] A saída deste programinha é:


Conteudo da matriz original:
0 1
1 2
Conteudo da matriz clonada:
0 1
1 2

Alterando valor do elemento [0][0]...

Conteudo da matriz original:
3 1
1 2
Conteudo da matriz clonada:
3 1
1 2

Perceberam que eu alterei somente o elemento [0][0] da matriz clonada, mas quando imprimi as duas, ambas estavam com este elemento igual a 3? Pois é… O que acontece é que o clone() não cria uma nova instância dos objetos que são atributos do objeto que você está clonando. Ele copia somente tipos primitivos. Os não primitivos apenas ganham uma nova referência apontando para eles. Se alguém souber porque isso foi implementado desta forma, por favor me avise!
Como uma matriz na verdade é um array de arrays, e em Java cada um destes arrays é um objeto, as linhas da matriz não sao clonadas. As referências para estas linhas, tanto na matriz original quanto na matriz clonada apontam para o mesmo lugar!

A solucao é implementar a interface Cloneable, que tem o método clone() (!!). Ali você explica como deve ser feita a clonagem. Crie novas instâncias de TUDO que não for tipo primitivo e defina seus respectivos estados como achar melhor.
E eu que perdi um dia inteiro sem entender porque meu programa estava doido…

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: