Java中的数据类型分为基本数据类型和引用数据类型,这两种数据类型在进行赋值操作、方法传参、作为返回值时会有值传递和引用传递的差别
1.对象拷贝分为深拷贝和浅拷贝
浅拷贝
1)对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将属性复制一份给新的对象,因为是两份不同的数据,所以对其中一个对象的该成员变量进行修改不会影响另一个拷贝得到的数据
2)对于引用型的成员变量,浅拷贝会进行引用传递,也就是将该成员变量的引用值(内存地址)复制一份给新的对象,因为实际上两个对象的该成员变量都指向同一个实例,在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量值
浅拷贝的一种实现方式:通过拷贝构造方法,实现浅拷贝
Person.java
package com.a_bean;
import java.io.Serializable;
public class Person implements Serializable{
private String name;
private String sex;
private Age age;
public Person(Person p ) {
this.name=p.name;
this.sex=p.sex;
this.age=p.age;
}
public void show() {
System.out.println("person showtime");
}
public Person() {
System.out.println("我是person(父类)无参构造器");
}
public Person(String name, String sex, Age age) {
this.name = name;
this.sex = sex;
this.age = age;
System.out.println("有");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";
}
}
Age.java
package com.a_bean;
import java.io.Serializable;
public class Age implements Serializable{
private int age;
public Age(int age) {
this.age=age;
}
public void setAge(int age) {
this.age=age;
}
public int getAge() {
return this.age;
}
public String toString() {
return getAge()+"";
}
}
测试类
package com.e_array;
import com.a_bean.Age;
import com.a_bean.Person;
/**
* 浅拷贝
* @author ylq
*
*/
public class ShallowCopy {
public static void main(String[] args) {
Age age = new Age(20);
Person p = new Person("张三","男",age);
Person p2 = new Person(p);
System.out.println(p);
System.out.println(p2);
p.setName("可以");
p.setSex("女");
age.setAge(10);
System.out.println(p);
System.out.println(p2);
}
}
结果:
结论:基本数据类型是值传递,所以修改后不会影响另一个对象的该属性值,引用类型是地址传递(引用传递),所以修改值后另一个对象的该属性值会同步被改变
深拷贝:通过对象序列化实现深拷贝
package com.e_array;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import com.a_bean.Age;
import com.a_bean.Person;
/**
* 通过对象序列化实现深拷贝
* @author ylq
*
*/
public class DeepCopy {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Age age = new Age(9);
Person p = new Person("张三","男",age);
Person p2 = new Person(p);
//通过序列化方法实现深拷贝
ByteArrayOutputStream bos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bos);
oos.writeObject(p);
oos.flush();
ObjectInputStream ois=new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
p2=(Person)ois.readObject();
System.out.println(p.toString());
System.out.println(p2.toString());
System.out.println();
age.setAge(990);
p.setName("小王");
p.setSex("女");
System.out.println(p.toString());
System.out.println(p2.toString());
}
}
结果:
Person [name=张三, sex=男, age=9]
Person [name=张三, sex=男, age=9]
Person [name=小王, sex=女, age=990]
Person [name=张三, sex=男, age=9]
结论:深拷贝是不会影响另一个拷贝对象的属性的