拷贝的概念
java中拷贝分为深拷贝
和浅拷贝
,对于基本数据类型拷贝的都是其值,而对于引用类型,拷贝的也是值,只不过引用类型拷贝的值是一个地址(java中只有值传递),对象还是原来的对象,这就是浅拷贝
。
也可以从内存上来说明,比如对象A,其是一个地址,存放在栈内。此时对A进行拷贝一份未B对象。如果是浅拷贝,那么B对象与A对象它们都指向一个相同地址。如果是深拷贝,A与B的对象指向的地址不一样,但其指向地址内的数据是一样的。
{mtitle title="浅拷贝"/}
{mtitle title="深拷贝"/}
Object类中clone()方法
- 实现Cloneable接口
- 重写clone()接口,super.clone();
public class Student implements Cloneable{
private String name;
private Integer age;
private Address address;
@Override
protected Student clone() throws CloneNotSupportedException {
return (Student)super.clone();
}
public void setAddress(Address address) {
this.address = address;
}
public Address getAddress() {
return address;
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", address=" + address +
'}';
}
}
public class Address{
private String name;
public Address(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Address{" +
"name='" + name + '\'' +
'}';
}
}
测试类
public class CopyTest {
public static void main(String[] args) throws CloneNotSupportedException {
Student stu = new Student();
stu.setName("cwl");
stu.setAge(18);
Address address = new Address("南京");
stu.setAddress(address);
Student cloneStu = stu.clone();
System.out.println(stu);
System.out.println(cloneStu);
System.out.println(stu == cloneStu);
}
}
// 运行结果
Student{name='cwl', age=18, address=Address{name='南京'}}
Student{name='cwl', age=18, address=Address{name='南京'}}
false
此时我们对address对象修改内容观察结果
public class CopyTest {
public static void main(String[] args) throws CloneNotSupportedException {
Student stu = new Student();
stu.setName("cwl");
stu.setAge(18);
Address address = new Address("南京");
stu.setAddress(address);
Student cloneStu = stu.clone();
cloneStu.getAddress().setName("苏州");
System.out.println(stu);
System.out.println(cloneStu);
}
}
// 运行结果
Student{name='cwl', age=18, address=Address{name='苏州'}}
Student{name='cwl', age=18, address=Address{name='苏州'}}
此时会发现,修改cloneStu对象中的address内容,原对象stu中的内容也发生了改变,所以这种克隆方式为浅克隆(浅拷贝)。
深拷贝的方式
通过流进行拷贝
注意: 拷贝的类包括其属性为引用属性都要实现Serializable接口,否则报错
/**
* 流拷贝
* @param obj
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public static Object streamCopy(Object obj) throws IOException, ClassNotFoundException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
使用fastjson复制
添加依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.71.android</version>
</dependency>
public static void main(String[] args) throws IOException{
Student stu = new Student();
stu.setName("cwl");
stu.setAge(18);
Address address = new Address("南京");
stu.setAddress(address);
String str = JSON.toJSONString(stu);
Student cloneStu = JSON.parseObject(str, Student.class);
cloneStu.getAddress().setName("苏州");
System.out.println(stu);
System.out.println(cloneStu);
}
这两种测试结果都为
Student{name='cwl', age=18, address=Address{name='南京'}}
Student{name='cwl', age=18, address=Address{name='苏州'}}
评论区