Java深拷贝浅拷贝

2019-08-14  本文已影响0人  Arvesynden

java.lang.Cloneable接口

一个带空体的接口称为标记接口(marker interface)

既不包含常量也不包含方法,用来表示一个类拥有某些特定的属性

实现Cloneable接口的类标记为可克隆的

浅复制(浅克隆)被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。

深复制(深克隆)被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。

Java 将内存空间分为堆和栈。基本类型直接在栈中存储数值,而引用类型是将引用放在栈中,实际存储的值是放在堆中,通过栈中的引用指向堆中存放的数据。

一个疑问:String作为引用类型,为什么它的浅复制也是直接复制的值呢?

String 类型很特殊,它是不可变类型,即一旦初始化后,就不可以改变。因为他为引用型,而且他指向的值为常量,克隆出来的对象改变他的值

实际上是改变了克隆出来对象String类型成员的指向,不会影响被克隆对象的。

解释:如果原来对象的一个string变量进行初始化的时候,指向的是一个字符串常量,该字符串常量会被放到常量池中,该string类型的引用将会指向该常量。进行克隆后,得到一个新的对象,如果该对象的string变量重新赋值,那么只会有这个string 引用变量指向一个新的内存区域,对原来对象中的string变量不会有影响。

public class Teacher implements Cloneable {

private String name;

private int id;

public Teacher(String name, int id) {

super();

this.name = name;

this.id = id;

}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@Override

protected Object clone() throws CloneNotSupportedException {

return super.clone();

}

}

public class CloneTest {

public static void main(String[] args) throws Exception {

Teacher t1 = new Teacher("张三", 1);

Teacher t3 = (Teacher) t1.clone();

System.out.println(t1.getName()+"\t"+t1.getId());

System.out.println(t3.getName()+"\t"+t3.getId());

System.out.println("----------浅克隆-----------");

System.out.println("t1:t3 "+t1.equals(t3));

System.out.println(t1);

System.out.println(t3);

t3.setName("李四");

System.out.println("修改后:");

System.out.println(t1.getName()+"\t"+t1.getId());

System.out.println(t3.getName()+"\t"+t3.getId());

}

}

下面这篇文章来自博客园YSOcean的讲解的十分清楚,让我受益匪浅。

https://www.cnblogs.com/ysocean/p/8482979.html

上一篇 下一篇

猜你喜欢

热点阅读