Cópia profunda (cópia profunda) e cópia superficial (cópia superficial) são dois conceitos relativamente comuns, especialmente na linguagem C++. Se você não entender, terá problemas ao excluir, mas felizmente estamos usando Java aqui. Embora Java gerencie automaticamente a reciclagem de objetos, ainda temos que prestar bastante atenção à cópia profunda (cópia profunda) e à cópia superficial (cópia superficial), porque às vezes esses dois conceitos costumam nos trazer muita confusão.
Cópia superficial significa que ao copiar um objeto, apenas o próprio objeto (incluindo as variáveis básicas do objeto) é copiado, mas o objeto apontado pela referência contida no objeto não é copiado. Uma cópia profunda não apenas copia o próprio objeto, mas também copia todos os objetos apontados pelas referências contidas no objeto. Por exemplo, para deixar mais claro: o objeto A1 contém uma referência a B1 e B1 contém uma referência a C1. A cópia superficial A1 para obter A2 ainda contém uma referência a B1 e B1 ainda contém uma referência a C1. Cópia profunda é a recursão da cópia profunda A1 para obter A2 contém uma referência a B2 (cópia de B1) e B2 contém uma referência a C2 (cópia de C1).
Se o método clone() não for reescrito, o objeto obtido ao chamar esse método será uma cópia superficial. Vamos nos concentrar na cópia profunda abaixo.
Execute o seguinte programa para dar uma olhada na cópia superficial:
class Professor0 implementa Cloneable { String name Professor0(String name, int age) { this.name = name; this.age = age } public Object clone() throws CloneNotSupportedException { return super.clone() ; class Student0 implementa Cloneable { String name; // Objeto constante. int idade; Professor0 p;//Os valores de referência do aluno 1 e do aluno 2 são iguais. Aluno0(String nome, int idade, Professor0 p) { this.name = name; this.age = idade; this.p = p } public Object clone() { Student0 o = null; .clone(); } catch (CloneNotSupportedException e) { System.out.println(e.toString() } return o; main(String[] args) { Professor0 p = new Professor0("wangwu", 50); Aluno0 s1 = novo Aluno0("zhangsan", 18, p); p.nome = "lisi"; System.out.println("Nome do aluno s1:" + s1.name + "/n Nome do professor do aluno s1:" + s1.p.name + "," + "/n Idade do professor do aluno s1" + s1 .p.age);//Professor do aluno 1} }
s2 mudou, mas s1 também mudou, provando que p de s1 e p de s2 apontam para o mesmo objeto. Este não é o caso das nossas necessidades reais, por isso precisamos de uma cópia profunda:
class Professor implementa Cloneable { String nome professor(String nome, int idade) { this.name = name; this.age = idade } public Object clone() { Object o = null; clone(); } catch (CloneNotSupportedException e) { System.out.println(e.toString() } return o; int idade; Aluno (String nome, int idade, Professor p) { this.name = name; this.age = idade; o = (Aluno) super.clone() } catch (CloneNotSupportedException e) { System.out.println(e.toString() } op = (Professor) p.clone(); return o; } } public class DeepCopy { public static void main(String args[]) { long t1 = System.currentTimeMillis(); = novo Aluno("zhangsan", 18, p); Aluno s2 = (Aluno) s1.clone(); s2.p.age = 30; System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age); // O professor do aluno 1 não muda. longo t2 = System.currentTimeMillis();
Claro, também temos um método de cópia profunda, que serializa o objeto:
import java.io.*; //Serialização é demorada class Professor2 implements Serializable { /** * */ private static final long serialVersionUID = 1L int age; nome = nome; this.age = idade; } } class Student2 implements Serializable { /** * */ private static final long serialVersionUID = 1L String name;// objeto constante. int idade; Professor2 p;//Os valores de referência do aluno 1 e do aluno 2 são iguais. Student2(String name, int age, Professor2 p) { this.name = name; this.age = age; this.p = p } public Object deepClone() throws IOException, OptionalDataException, ClassNotFoundException { // Grava o objeto no fluxo Em ByteArrayOutputStream bo = new ByteArrayOutputStream(); oo.writeObject(this); // Ler ByteArrayInputStream do fluxo bi = new ByteArrayInputStream(bo.toByteArray()); /** * @param args */ public static void main(String[] args) lança OpcionalDataException, IOException, ClassNotFoundException { long t1 = System.currentTimeMillis(); Professor2 p = new Professor2("wangwu", 50); ();s2.p.nome = "lisi"; System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age); // O professor do aluno 1 não muda. longo t2 = System.currentTimeMillis();
No entanto, a serialização consome muito tempo. Em alguns frameworks, podemos sentir que eles frequentemente serializam objetos e depois os transferem, o que leva muito tempo.