Método clone()
Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy — lição 43 de 87.
O método clone() cria uma cópia de um objeto. Para usá-lo, sua classe deve implementar a interface Cloneable e sobrescrever o método clone() da classe Object.
public class Person implements Cloneable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Person clone() {
try {
return (Person) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}Agora você pode criar cópias independentes de objetos:
Person original = new Person("Alice", 25);
Person copy = original.clone();
// copy é um objeto separado com os mesmos valoresPor padrão, clone() realiza uma cópia rasa (shallow copy), o que significa que ele copia valores primitivos e referências. Se o seu objeto contiver outros objetos como campos, tanto o original quanto o clone referenciarão os mesmos objetos aninhados. Para cópias verdadeiramente independentes com objetos aninhados, você precisa implementar uma cópia profunda (deep copy), clonando também esses objetos aninhados dentro do seu método clone().
Desafio
FácilVamos construir um sistema de gerenciamento de documentos que demonstra a clonagem de objetos. Você criará uma classe Document que pode ser clonada para criar cópias independentes, permitindo que os usuários dupliquem documentos mantendo o original intacto.
Você organizará seu código em dois arquivos:
Document.java: Crie uma classe que representa um documento que suporta clonagem. Um Document possui três campos privados:title(String),author(String) eversion(int). Inclua um construtor para inicializar todos os campos e métodos getter para cada um. Adicione também um métodosetVersion(int version)para atualizar o número da versão.Faça sua classe Document implementar a interface
Cloneablee sobrescreva o métodoclone()para retornar umDocument. Trate aCloneNotSupportedExceptiondentro do método envolvendo-a em umaRuntimeException.Sobrescreva
toString()para retornar:Document[title=X, author=Y, version=Z]onde X, Y e Z são os valores reais dos campos.Main.java: Dê vida à sua classe Document criando um documento e clonando-o. Você receberá três entradas: um título (String), um autor (String) e um número de versão (int).Crie um Document original com esses valores e, em seguida, clone-o para criar uma cópia. Após a clonagem, modifique a versão da cópia incrementando-a em 1 usando
setVersion(). Isso demonstra que o clone é verdadeiramente independente do original.Imprima três linhas:
Original:seguido pelo toString() do documento originalClone:seguido pelo toString() do documento clonadoIndependent:seguido portrueoufalseindicando se o original e o clone são objetos diferentes (use a comparação!=)
Você receberá três entradas: o título do documento (String), o nome do autor (String) e o número da versão (int).
Observe como, após modificar a versão do clone, o documento original permanece inalterado — isso prova que o clone() criou uma cópia verdadeiramente independente!
Folha de consulta
O método clone() cria uma cópia de um objeto. Para usá-lo, sua classe deve implementar a interface Cloneable e sobrescrever o método clone() da classe Object:
public class Person implements Cloneable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Person clone() {
try {
return (Person) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}Criando cópias independentes:
Person original = new Person("Alice", 25);
Person copy = original.clone();
// copy é um objeto separado com os mesmos valoresPor padrão, o clone() realiza uma cópia rasa (shallow copy), copiando valores primitivos e referências. Se o seu objeto contiver outros objetos como campos, tanto o original quanto o clone referenciarão os mesmos objetos aninhados. Para cópias verdadeiramente independentes com objetos aninhados, implemente uma cópia profunda (deep copy) clonando também esses objetos aninhados dentro do seu método clone().
Experimente você mesmo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Ler entradas
String title = scanner.nextLine();
String author = scanner.nextLine();
int version = scanner.nextInt();
// TODO: Criar um Documento original com os valores de entrada
// TODO: Clonar o documento original para criar uma cópia
// TODO: Modificar a versão do clone incrementando-a em 1
// TODO: Imprimir "Original: " seguido pelo documento original
// TODO: Imprimir "Clone: " seguido pelo documento clonado
// TODO: Imprimir "Independent: " seguido por true/false (verificar se original != clone)
}
}Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave thisMétodosCampos (Atributos)Método ConstrutorSobrecarga de ConstrutorRecapitulação - Calculadora Simples4Herança
Herança Básica (extends)A Palavra-chave superSobrescrita de Método (@Override)Encadeamento de ConstrutoresA Classe ObjectHerança Simples e MultinívelPor que não há Herança Múltipla de ClassesRecapitulação - Hierarquia de Funcionários7Métodos Especiais e a Classe Object
Método toString()equals() e hashCode()Método clone()compareTo() e ComparableInterface ComparatorRecapitulação - Ordenação Personalizada2Modificadores de Acesso e Encapsulamento
Visão Geral dos Níveis de AcessoMétodos Getter e SetterOcultação de InformaçõesA Palavra-chave finalRecapitulação - Gerenciador de Conta Bancária5Polimorfismo
Fundamentos de Sobrecarga de MétodosSobrescrita de Métodos (Tempo de Execução)Upcasting e DowncastingO Operador instanceofClasses e Métodos AbstratosRecapitulação - Calculadora de Formas8Conceitos Avançados de OOP
Composição vs HerançaAgregação vs ComposiçãoClasses Internas, Aninhadas e AnônimasEnums e Métodos de EnumRecords (Java 16+)Classes Seladas (Java 17+)11Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão BuilderPadrão ObserverPadrão Strategy3Propriedades de Classe e Membros Estáticos
Variáveis de Instância vs EstáticasMétodos EstáticosBlocos EstáticosConstantes (static final)Recapitulação - Contador e Utilitário6Interfaces e Classes Abstratas
Introdução às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesDefault e Static em InterfacesClasses Abstratas vs InterfacesInterfaces FuncionaisRecapitulação - Sistema de Pagamento9Generics
Introdução a GenericsClasses GenéricasMétodos GenéricosParâmetros de Tipos DelimitadosWildcards (?, extends, super)Recapitulação - Container Genérico12Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão Iterator