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?