浅拷贝
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
Student student1 =new Student();
student1.setAge(23);
student1.setName("liqitian3344");
Student student3 = student1;
System.out.println(student1);
System.out.println(student3);
//结果如下
Student(age=23, name=liqitian3344)
Student(age=23, name=liqitian3344)
这样大致看一下也像是那么回事,看下面Student student1 =new Student();
student1.setAge(23);
student1.setName("liqitian3344");
Student student3 = student1;
//这里 操作了一下 student3,student1.setAge(100); 也能达到同样的效果
student3.setAge(100);
System.out.println(student1);
System.out.println(student3);能看出 这种方式只是把Student的引用student1拷贝一份student3,他们指向的是同一个new Student(),所以这种方式达不到浅赋值的程度。
总所周知,java要实现对象复制,预复制对象要实现Cloneable接口并重写clone方法(见实例类Student),该接口是个标志接口源码如下
public interface Cloneable {}再看一种情况(浅复制)
Student student1 = new Student();
student1.setAge(23);
student1.setName("liqitian3344");
Student student2 = (Student) student1.clone();
student2.setAge(80);
System.out.println(student1);
System.out.println(student2);
String result = student1.getName() == student2.getName() ? "浅" : "深";
System.out.println(result);
//结果
Student(age=23, name=liqitian3344)
Student(age=80, name=liqitian3344)
浅嗯 这个看起来像是那么回事,下面看个不像那么回事的
新实例类如下
@Data
class Student implements Cloneable {
private int age;
private String name;
private Book book;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
@Data
class Book{
private String bookName;
}在写段代码测一下
Book book = new Book();
book.setBookName("语文");
Student student1 = new Student();
student1.setAge(23);
student1.setName("liqitian3344");
student1.setBook(book);
Student student2 = (Student) student1.clone();
student2.setAge(100);
book.setBookName("数学");
System.out.println(student1);
System.out.println(student2);
String result = student1.getName() == student2.getName() ? "clone是浅拷贝的" : "clone是深拷贝的";
System.out.println(result);
//结果如下
Student(age=23, name=liqitian3344, book=Book(bookName=数学))
Student(age=100, name=liqitian3344, book=Book(bookName=数学))
clone是浅拷贝的好了 浅赋值结论:会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。
深拷贝
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
深拷贝就没什么好说的了,记住上面的概念就好,深拷贝的实现方式有两种
1. 继续使用clone();方法就是在上面Student中clone()方法重写成下面的样子
@Data
class Student implements Cloneable {
private int age;
private String name;
private Book book;
@Override
protected Object clone() throws CloneNotSupportedException {
Student student = (Student) super.clone();
book = (Book) book.clone();
return student; }
}测试代码同上
2. 序列化实现对象深拷贝,下面直接代码了
//将对象写入流中
Student student1 = new Student();
ByteArrayOutoutStream bo=new ByteArrayOutputStream();
ObjectOutputStream oo=new ObjectOutputStream(bo);
oo.writeObject(student1);
//从流里读出
ByteArrayInputStream bi=new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi=new ObjectInputStream(bi);
return(oi.readObject());