在Java中,除了基本数据类型之外,还存在引用类型,在方法参数传递时,对于基本数据类型,实际上是值传递,引用类型则是地址传递,将原对象的引用传递过去,他们实际上还是指向同一个对象,String是一种特殊的引用类型,有些值类型的样子,,使得它也相当于值传递。
而浅拷贝和深拷贝就是在这个基础之上做的区分,如果在拷贝这个对象时,只对基本数据类型、String进行了拷贝,而对引用数据类型只是进行了引用的传递,而没有真实的创建一个新的对象,则认为是浅拷贝。反之,再对引用数据类型进行拷贝的时候,创建了一个新的对象,而且复制其内的成员变量,则认为是深拷贝。
所以所谓的浅拷贝和深拷贝,只是在拷贝对象的时候,对类的实例对象这种引用数据类型的不同操作而已。
-
浅拷贝:对基本数据类型进行值拷贝,引用数据类型只是引用地址拷贝,此为浅拷贝
image.png -
深拷贝:对基本数据类型进行值拷贝,引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝
image.png
下面是一个深拷贝的例子
//Cloneable 接口,可以看到它其实什么方法都不需要实现。对他可以简单的理解只是一个标记,是开发者允许这个对象被拷贝。
public class Person implements Cloneable {
public int age;
public String name;
public List<String> hobbyList;
public List<Book> bookList;
@Override
protected Object clone() throws CloneNotSupportedException {
//super.clone()浅拷贝,使得age、name完成了值拷贝
Person p = (Person) super.clone();
//hobbyList、bookList为引用类型,需要进行深度拷贝
//List<String>只需要完成浅拷贝即可
p.hobbyList = (List<String>) ((ArrayList<String>) hobbyList).clone();
List<Book> books = new ArrayList<>();
for (Book book : bookList) {
books.add((Book) book.clone());
}
p.bookList = books;
return p;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
", hobbyList=" + hobbyList +
", bookList=" + bookList +
'}';
}
}
public class Book implements Cloneable {
public String bookName;
public float price;
public Book(String bookName, float price) {
this.bookName = bookName;
this.price = price;
}
@Override
protected Object clone() throws CloneNotSupportedException {
//String、float不需要进行深度拷贝
return super.clone();
}
@Override
public String toString() {
return "Book{" +
"bookName='" + bookName + '\'' +
", price=" + price +
'}';
}
}
public class Test {
public static void main(String[] args) {
Person p = new Person();
p.name = "小红";
p.age = 10;
p.hobbyList = new ArrayList<>();
p.hobbyList.add("旅游");
p.hobbyList.add("跑步");
p.bookList = new ArrayList<>();
p.bookList.add(new Book("追忆似水年华", 80.0f));
p.bookList.add(new Book("悲惨世界", 66.0f));
//对Person p进行深度拷贝
Person pCopy = null;
try {
pCopy = (Person) p.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
pCopy.name = "小明";
pCopy.age = 15;
pCopy.hobbyList.set(0, "读书");
pCopy.bookList.set(0, new Book("简爱", 50.0f));
System.out.println(p.toString());
System.out.println(pCopy.toString());
}
}
网友评论