Clonagem de Objetos em Java: Cópia Profunda e Superficial

Concetio de Clonagem

Em Java, frequentemente necessitamos criar uma réplica independente de um objeto existente, onde modificações na cópia não afetam o original. A clonagem oferece uma solução eficiente para esse cenário. Todos os herdam de java.lang.Object, que contém o método clone(), responsável por gerar uma nova instância com valores idênticos ao objeto atual.

Implementando o Método clone()

Para habilitar a clonagem, a classe deve implementar a interface Cloneable e sobrescrever clone() com acesso público:

class ExemploClonagem implements Cloneable {
    int valor;
    
    @Override
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

Pontos essenciais:

  • Cloneable atua como marcador, permitindo que Object.clone() execute
  • Chamada super.clone() utiliza o mecanismo nativo eficiente da JVM
  • Sem Cloneable, clone() lança CloneNotSupportedException

Cópia Superficial vs Profunda

Cópia Superficial: Duplica apenas o objeto base, mantendo referências aos mesmos objetos internos.

Cópia Profunda: Clona recursivamente todo o grafo de objetos, criando novas instâncias para todos os componentes.

Exemplo de Cópia Superficial

class Professor implements Cloneable {
    String nome;
    int idade;
    // Método clone padrão (superficial)
}

class Aluno implements Cloneable {
    String nome;
    Professor tutor;
    
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone(); // Clona apenas Aluno, mantendo referência ao mesmo Professor
    }
}

Exemplo de Cópia Profunda

class Aluno implements Cloneable {
    String nome;
    Professor tutor;
    
    @Override
    public Object clone() throws CloneNotSupportedException {
        Aluno copia = (Aluno) super.clone();
        copia.tutor = (Professor) tutor.clone(); // Clona o objeto interno
        return copia;
    }
}

Cópia Profunda via Serialização

Alternativa para objetos complexos implementando Serializable:

class Estudante implements Serializable {
    Professor orientador;
    
    public Object deepClone() throws IOException, ClassNotFoundException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        ObjectOutputStream saida = new ObjectOutputStream(buffer);
        saida.writeObject(this);
        
        ByteArrayInputStream entradaBytes = new ByteArrayInputStream(buffer.toByteArray());
        ObjectInputStream entrada = new ObjectInputStream(entradaBytes);
        return entrada.readObject();
    }
}

Observação: Esta abordagem é mais custosa computacionalmente devido ao processamento de I/O.

Tags: java Object Cloning deep copy shallow copy Serialization

Publicado em 7-9 04:50