Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
1
resposta

Referência a um Objeto

Olá Boa tarde!
Quando faço referência a um objeto (exemplo: Filme f1 = FilmeDoPaulo; - exemplo dado na aula)
Eu nao estou "clonando" o objeto, mas sim criando uma novo nome para acessar o mesmo objeto?
Tipo fulano tem um nome e um apelido?

mas ai, se eu quiser de fato clonar o objeto como eu poderia fazer?
muitas vezes eu preciso manipular os dados do objeto mas para algum fim, porem preciso manter o original.
ex1: talvez mudar o nome de um filme (Senhor dos anéis para LOTR), para algum uso pontual, mas nao seria bom perder o nome pois e usado em outros lugares...

ex2: uma lista de filmes eu poderia filtrar os que tivessem boa avaliação e armazenar, mas não seria bom perder a lista completa ou algo assim...

1 resposta
solução!

Olá, Diegho! Boa tarde, e que ótima pergunta!

Você está completamente certo em seu raciocínio. Quando fazemos Filme f1 = filmeDoPaulo; em Java, não estamos clonando o objeto, mas sim criando uma nova referência que aponta para o mesmo objeto já existente na memória. A analogia que você usou é perfeita: é exatamente como uma pessoa ter um nome e um apelido. Ambos identificam a mesma pessoa, assim como f1 e filmeDoPaulo apontam para o mesmo objeto.

Agora, para de fato clonar um objeto e manter o original intacto, precisamos de uma abordagem diferente. Um exemplo muito utilizado em Java é implementar a interface Cloneable e sobrescrever o método clone() na sua classe. Veja como poderia ficar:

class Filme implements Cloneable {
    private String nome;
    private int classificacao;

    // Construtor, getters e setters omitidos para brevidade

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

public class Main {
    public static void main(String[] args) {
        try {
            Filme filmeDoPaulo = new Filme();
            filmeDoPaulo.setNome("Senhor dos Aneis");
            filmeDoPaulo.setClassificacao(5);

            Filme f1 = (Filme) filmeDoPaulo.clone();
            f1.setNome("LOTR");

            System.out.println("Nome original: " + filmeDoPaulo.getNome());
            System.out.println("Nome clonado: " + f1.getNome());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

Neste exemplo, f1 passa a ser uma cópia independente de filmeDoPaulo. Qualquer alteração feita em f1, como mudar o nome do filme de "Senhor dos Anéis" para "LOTR", não afeta o objeto original. Isso resolve exatamente o problema que você descreveu no primeiro exemplo.

Para o segundo caso, com uma lista de filmes, o raciocínio é parecido. Você poderia criar uma nova lista e adicionar cópias clonadas dos objetos que precisa filtrar, como os filmes com boa avaliação, sem perder a lista completa original. Se os objetos da lista implementarem Cloneable, o processo de clonagem individual de cada item funciona bem. Caso contrário, uma alternativa é criar novas instâncias manualmente, copiando os valores um a um.

Vale mencionar também que existe o conceito de cópia profunda, chamada de deep copy, que se torna necessária quando o objeto possui atributos que são, eles mesmos, outros objetos. Nesse caso, o clone() padrão pode não ser suficiente, pois ele realiza apenas uma cópia rasa, conhecida como shallow copy. Mas isso é um assunto para explorar com calma conforme você avança nos estudos.

Espero ter ajudado a esclarecer essa diferença tão importante entre referência e cópia em Java. Bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.

Você já teve alguma situação prática, seja em um exercício ou projeto, em que modificou um objeto sem querer e perdeu dados importantes por não conhecer essa diferença entre referência e clonagem?