Welcome to Our Website

Shallow vs. Deep Copy in Java (Português)

In this article from my free Java 8 Course, I will be discussing the difference between a Deep and a Shallow Copy. Você pode baixar os slides e o artigo como PDF aqui.

o que é uma cópia?

para começar, gostaria de destacar o que é uma cópia em Java. Primeiro, vamos diferenciar entre uma cópia de referência e uma cópia de objeto. Uma cópia de referência, como o nome indica, cria uma cópia de uma variável de referência que aponta para um objeto., Se temos um objeto de carro, com uma variável myCar apontando para ele e fazemos uma cópia de Referência, agora teremos duas variáveis myCar, mas ainda um objeto.

exemplo 1

uma cópia de um objecto cria uma cópia do próprio objecto. Então, se copiássemos novamente o objeto do carro, criaríamos uma cópia do objeto em si, bem como uma segunda variável de referência referenciando aquele objeto copiado.

Exemplo 2

o Que É um Objeto?,

tanto uma cópia profunda como uma cópia Rasa são tipos de cópias de objetos, mas o que realmente é um objeto? Muitas vezes, quando falamos sobre um objeto, falamos dele como uma única unidade que não pode ser quebrada mais, como um humilde grão de café. No entanto, isso é simplificado demais.

exemplo 3

digamos que temos um objecto pessoal. Nosso objeto pessoal é de fato composto de outros objetos, como você pode ver no exemplo 4. Nossa pessoa contém um objeto nome e um objeto endereço., O nome por sua vez, contém um nome próprio e um objeto de LastName; o objeto de endereço é composto de um objeto de rua e um objeto de Cidade. Então, quando eu falo sobre pessoas neste artigo, eu estou falando sobre toda essa rede de objetos.

Exemplo 4

Então, por que iríamos querer copiar este objeto Pessoa? Uma cópia de objeto, geralmente chamada de clone, é criada se quisermos modificar ou mover um objeto, preservando o objeto original. Existem muitas maneiras diferentes de copiar um objeto que você pode aprender sobre em outro artigo., Neste artigo, usaremos especificamente um construtor de cópias para criar as nossas cópias.

cópia Rasa

primeiro vamos falar sobre a cópia rasa. Uma cópia rasa de um objeto copia o objeto ‘principal’, mas não copia os objetos internos. Os “objetos internos” são compartilhados entre o objeto original e sua cópia. Por exemplo, em nosso objeto pessoal, nós criaríamos uma segunda pessoa, mas ambos os objetos compartilhariam o mesmo nome e objetos de endereço.

vamos olhar para um exemplo de codificação. No exemplo 5, temos nossa pessoa de classe, que contém um nome e objeto de endereço., O construtor de cópias pega no objecto original e copia as suas variáveis de referência.

Exemplo 5

O problema com a cópia superficial é que os dois objetos não são independentes. Se você modificar o objeto do nome de uma pessoa, a mudança será refletida no objeto da outra pessoa.vamos aplicar isto a um exemplo. Digamos que temos um objeto de pessoa com uma variável de referência mãe; então, fazemos uma cópia da mãe, criando um objeto de segunda pessoa, filho. Se mais tarde no código, o filho tenta mover – se () modificando seu objeto de endereço, a mãe se move com ele!,

Person mother = new Person(new Name(…), new Address(…));Person son = new Person(mother);son.moveOut(new Street(…), new City(…));

exemplo 6

isto ocorre porque os nossos objectos mãe e filho partilham o mesmo objecto de endereço, como pode ver ilustrado no exemplo 7. Quando mudamos o endereço em um objeto, ele muda em ambos!

Exemplo 7

Cópia de Profundidade

ao contrário da cópia superficial, uma cópia profunda é totalmente independente cópia de um objeto. Se copiássemos o nosso objecto pessoal, copiaríamos toda a estrutura do objecto.,

Exemplo 8

Uma mudança no objeto de Endereço de uma Pessoa não estaria refletida no outro objeto, como você pode ver pelo diagrama no Exemplo 8. Se dermos uma olhada no código no exemplo 9, Você pode ver que não estamos apenas usando um construtor de cópias em nosso objeto pessoal, mas também estamos utilizando construtores de cópias nos objetos internos.

exemplo 9

Usando esta cópia profunda, podemos repetir o exemplo mãe-filho do exemplo 6. Agora o filho é capaz de sair com sucesso!,no entanto, isso não é o fim da história. Para criar uma verdadeira cópia profunda, precisamos continuar copiando todos os elementos aninhados do objeto da pessoa, até que haja apenas tipos primitivos e “imutáveis” deixados. Vamos olhar para a classe de rua Para ilustrar melhor isto:

exemplo 10

o objeto de rua é composto por duas variáveis de instância – nome de cadeia e número int. o número int é um valor primitivo e não um objeto. É apenas um valor simples que não pode ser compartilhado, então ao criar uma variável de segunda instância, estamos criando automaticamente uma cópia independente., A corda é imutável. Em suma, um imutável é um objeto, que, uma vez criado, nunca mais pode ser mudado. Portanto, você pode compartilhá-lo sem ter que criar uma cópia profunda dele.

conclusão

para concluir, gostaria de falar sobre algumas técnicas de codificação que usamos no nosso exemplo mãe-filho. Só porque uma cópia profunda lhe permitirá alterar os detalhes internos de um objeto, como o objeto de Endereço, isso não significa que você deve., Fazê – lo diminuiria a qualidade do Código, uma vez que tornaria a classe da pessoa mais frágil para as mudanças-sempre que a classe de Endereço for alterada, você terá (potencialmente) de aplicar mudanças na classe da pessoa também. Por exemplo, se a classe de endereço não contém mais um objeto de rua, teríamos que mudar o método moveOut() na classe de pessoas em cima das mudanças que já fizemos na classe de endereço.

no exemplo 6 deste artigo eu apenas escolhi usar um novo objeto de rua e cidade para ilustrar melhor a diferença entre uma cópia rasa e uma cópia profunda., Em vez disso, eu recomendo que você atribuir um novo Endereço de objecto em vez de, efetivamente, a conversão para um híbrido de uma rasa e uma cópia profunda, como você pode ver no Exemplo 10:

Person mother = new Person(new Name(…), new Address(…));Person son = new Person(mother);son.moveOut(new Address(...));

Exemplo 11

orientados a objetos termos, isso viola o encapsulamento, e, portanto, deve ser evitado. Encapsulamento é um dos aspectos mais importantes da programação orientada a objetos. Neste caso, eu tinha violado encapsulamento ao acessar os detalhes internos do objeto de endereço em nossa classe pessoal., Isso prejudica o nosso código porque agora temos enredado a classe da pessoa na classe de endereço e se fizermos mudanças na classe de endereço abaixo da linha, isso pode prejudicar a classe da pessoa como eu expliquei acima. Enquanto você obviamente precisa interconectar suas várias classes para ter um projeto de codificação, sempre que você conectar duas classes, você precisa analisar os custos e benefícios.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *