1. 深拷贝和浅拷贝
在java中,如果某个类需要调用Object的clone完成对象的拷贝,必须让该类实现。
浅拷贝:object类,提供的clone方法就是浅拷贝(对象)。
举例:
public class user implements Cloneable{
String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String toString() {
return "user{" +
"username='" + username + '\'' +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class test {
public static void main(String[] args) throws CloneNotSupportedException {
user user = new user();
user.setUsername("faye");
user user1 = (user) user.clone();
user.setUsername("spike");
System.out.println(user1);
System.out.println(user);
}
}
运行结果:
user{username='faye'}
user{username='spike'}
结论:我们可以看见user1还是faye,说明把之前的user复制过来了,但是又给user重新给了一个新的值之后,user1并没有变化,说明已经是一个新的对象了。
所以我们又把新给的那个给注释掉来一次测试:
public class test {
public static void main(String[] args) throws CloneNotSupportedException {
user user = new user();
user.setUsername("faye");
user user1 = (user) user.clone();
// user.setUsername("spike");
System.out.println(user1);
System.out.println(user);
System.out.println(user == user1);
}
}
运行结果:
user{username='faye'}
user{username='faye'}
false
结论:由此可见,user和user1并不是同一个对象,他们只是值相等。
测试:(增加一个新的对象)
user类:
public class user implements Cloneable{
String username;
Dog dog;
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String toString() {
return "user{" +
"username='" + username + '\'' +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Dog类:
public class Dog {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dog(String name) {
this.name = name;
}
public Dog(){
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
'}';
}
}
测试:
public static void main(String[] args) throws CloneNotSupportedException {
user use = new user();
use.setUsername("faye");
use.setDog(new Dog("Ein"));
user use1 = new user();
use1 = (user) use.clone();
use.setUsername("spike");
System.out.println(use);
System.out.println(use1);
System.out.println(use.getDog().getName());
System.out.println(use1.getDog().getName());
use.getDog().setName("Ein2");
System.out.println(use.getDog().getName());
System.out.println(use1.getDog().getName());
}
}
运行结果:
user{username='spike'}
user{username='faye'}
Ein
Ein
Ein2
Ein2
结论:user的dog名字改变,user1的dog的名字也随之改变说明在进行对象拷贝时候,仅仅完成了对象的第一层拷贝,如果该对象存在着子对象,则不会拷贝子对象。
深拷贝:
1、让子对象也实现Cloneable接口,在父对象进行拷贝是,子对象也同时拷贝
2、通过序列化对象和反序列化来实现深拷贝
在clone方法中把子对象也进行复制
public class user implements Cloneable{
String username;
Dog dog;
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String toString() {
return "user{" +
"username='" + username + '\'' +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
// return super.clone();
user user = (user) super.clone();
user.dog = (Dog) dog.clone();
return user;
}
}
dog类也实现cloneable的接口
public class Dog implements Cloneable{
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dog(String name) {
this.name = name;
}
public Dog(){
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
test
public class test {
public static void main(String[] args) throws CloneNotSupportedException {
user use = new user();
use.setUsername("faye");
use.setDog(new Dog("Ein"));
user use1 = new user();
use1 = (user) use.clone();
use.setUsername("spike");
System.out.println(use);
System.out.println(use1);
System.out.println(use.getDog().getName());
System.out.println(use1.getDog().getName());
use.getDog().setName("Ein2");
System.out.println(use.getDog().getName());
System.out.println(use1.getDog().getName());
}
}
运行结果:
user{username='spike'}
user{username='faye'}
Ein
Ein
Ein2
Ein
结论:user的dog名字改变,user1的dog名字没有进行改变,说明拷贝成功了。