java对象的浅拷贝与深拷贝
·
1、含义
浅拷贝:一个对象在被拷贝后,两个对象完全相同,指向的地址一致,修改其中一个对象中的变量,另一个对象也相应发生改变。
深拷贝:一个对象在被拷贝后,两个对象相同,但相互独立,指向的地址不同,修改其中一个对象中的变量,另一个对象不会发生改变。
2、实际案例
2.1 浅拷贝
在示例中,我们将对象person01直接赋值给变量声明person02,在赋值过程中,实际上是把person01指向的地址给person02指向,所以person01和person02两个对象指向的地址一致。
所以在浅拷贝中,更改一个对象的变量后,指向同样地址的对象中的变量自然也发生了改变。
示例代码

运行结果

2.1 深拷贝
在示例中,我们分别创建了person01和person02两个对象,并将person01中的变量的值赋值给person02中的变量,在这个过程中person01和person02分别指向了两个不同的地址,并进行赋值操作,在后面对person01进行更改后,对person02并无影响,就是因为两个对象的指向不同。
通俗易懂的来说,要复制的对象是person01,我们先创建同属于Person类的person02,再将person01的属性值赋值给person02,这就是深拷贝。
示例代码

运行结果

3、深拷贝的三种方式
3.1 直接创建对象,再赋值

3.2重写clone方法(也可以自定义其它方法)


3.3 通过序列化实现深拷贝

4、注意事项
其实在Person person = new Person();中,这也是一次浅拷贝,将右边创建出来的对象地址赋给左边的变量声明。
在深拷贝过程中要注意,拷贝对象中有无类属性变量,有的话,该变量也要做相应的深拷贝处理。
5、示例代码
import java.io.*;
public class Example03 {
public static void main(String[] args) {
// java对象的浅拷贝与深拷贝
System.out.println("--------------------------------浅拷贝------------------");
shallowCopy();
System.out.println("----------------------------直接创建对象,再赋值-----------");
deepCopy01();
System.out.println("-------------------------------重写clone方法-------------");
deepCopy02();
System.out.println("---------------------------通过序列化实现深拷贝-------------");
deepCopy03();
}
public static void shallowCopy() {
Person person01 = new Person();
person01.name = "小明";
person01.age = 18;
Person person02 = person01;
System.out.println("person01:" + person01);
System.out.println("person02:" +person02);
System.out.println("-----------对person01的name字段进行更改后");
person01.name = "小红";
System.out.println("person01:" + person01);
System.out.println("person02:" +person02);
}
// 直接创建对象,再赋值
public static void deepCopy01() {
Person person01 = new Person();
person01.name = "小明";
person01.age = 18;
Person person02 = new Person();
person02.name = person01.name;
person02.age = person01.age;
System.out.println("person01:" + person01);
System.out.println("person02:" +person02);
System.out.println("-----------对person01的name字段进行更改后");
person01.name = "小红";
System.out.println("person01:" + person01);
System.out.println("person02:" +person02);
}
// 重写clone方法(也可以自定义其它方法)
public static void deepCopy02() {
Person person01 = new Person();
person01.name = "小明";
person01.age = 18;
Person person02 = person01.clone();
person02.name = person01.name;
person02.age = person01.age;
System.out.println("person01:" + person01);
System.out.println("person02:" +person02);
System.out.println("-----------对person01的name字段进行更改后");
person01.name = "小红";
System.out.println("person01:" + person01);
System.out.println("person02:" +person02);
}
// 通过序列化实现深拷贝
public static void deepCopy03() {
Person person01 = new Person();
person01.name = "小明";
person01.age = 18;
Person person02 = person01.deepSerializable();
person02.name = person01.name;
person02.age = person01.age;
System.out.println("person01:" + person01);
System.out.println("person02:" +person02);
System.out.println("-----------对person01的name字段进行更改后");
person01.name = "小红";
System.out.println("person01:" + person01);
System.out.println("person02:" +person02);
}
}
class Person implements Serializable {
public String name;
public int age;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public Person clone() {
Person person = new Person();
person.name = this.name;
person.age = this.age;
return person;
}
public Person deepSerializable() {
try {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(this);
objectOutputStream.flush();
objectOutputStream.close();
byteArrayOutputStream.close();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
return (Person) objectInputStream.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
更多推荐


所有评论(0)