场景
在实际编程中需要两个相互独立的对象A,B,对象B的初始数据和A一致。改变对象B不会影响对象A。
错误用法
User user1 = new User();
user1.setAge(18);
User user2 = new User();
user2 = user1;
user2.setAge(19);
System.out.println("user1.age="+user1.getAge());
System.out.println("user2.age="+user2.getAge());
从结果看,改变stu2,stu1也改变了。(stu2 = stu1)的作用是将stu1的引用赋值给stu2,这样,stu1和stu2指向内存堆中同一个对象。
该方法仅适用于值类型,对于引用类型就会出现改变一个对象,另一个也改变。
值类型:四类八种
1,整型3种 byte,short,int,long
2,浮点型2种 float,double
3,字符型1种 char
4,逻辑型1种 boolean
引用类型:(数组,类,接口)
String,Integer也是引用类型,是类。String可以直接赋值,而两个对象不相互影响是因为String是不可变类型。
即值不可改变,可以改变指向,直接赋值就是重开辟一个地址,将新值保存。所以直接复制后,两个对象相互不影响。
通过set方法,将A对象值赋给B对象
User.java
@Data
public class User{
private String name;
private String sex;
@Max(value=10,message = "年龄不能超过10岁。")
private int age;
}
调用方法
Student stu1 = new Student();
stu1.setAge(18);
Student stu2 = new Student();
stu2.setAge(stu1.getAge());
stu2.setAge(19);
System.out.println("学生1="+stu1.getAge()); --18
System.out.println("学生2="+stu2.getAge()); --19
缺点:对象属性较多时比较麻烦
重写java.lang.Object类中的方法clone()
浅克隆:不支持引用类型复制(子对象不复制)
在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。
1.被复制的类需要实现Clonenable接口
2.覆盖clone()方法,访问修饰符设为public。方法中调用super.clone()方法得到需要的复制对象。
User.java: 要复制的对象类中重写clone方法
@Data
public class User implements Cloneable{
private String name;
private String sex;
@Max(value=10,message = "年龄不能超过10岁。")
private int age;
@Override
public Object clone(){
User user = null;
try{
user = (User)super.clone();
}catch (CloneNotSupportedException e){
System.out.println(e.getMessage());
}
return user;
}
}
调用方法:
User user1 = new User();
user1.setAge(18);
User user2 = (User)user1.clone();
user2.setAge(19);
System.out.println("user1.age="+user1.getAge());
System.out.println("user2.age="+user2.getAge());
深克隆:支持引用类型复制
User.java 类中追加Address类型的变量
@Data
public class User implements Cloneable{
private String name;
private String sex;
@Max(value=10,message = "年龄不能超过10岁。")
private int age;
private Address address;
@Override
public Object clone(){
User user = null;
try{
user = (User)super.clone();
}catch (CloneNotSupportedException e){
System.out.println(e.getMessage());
}
return user;
}
}
Address.java
@Data
public class Address {
private String address;
}
调用方法:
Address a = new Address();
a.setAddress("山东");
User user1 = new User();
user1.setAddress(a);
User user2 = (User)user1.clone();
a.setAddress("上海");
System.out.println("user1.address="+user1.getAddress());--上海
System.out.println("user2.address="+user2.getAddress());--上海
此时,子对象并未被真正复制。想要真正复制,需要将子类的clone的方法也重写。
Address.java
@Data
public class Address implements Cloneable{
private String address;
@Override
public Object clone(){
Address address = null;
try{
address = (Address)super.clone();
}catch (CloneNotSupportedException e){
System.out.println(e.getMessage());
}
return address;
}
}
User.java
@Data
public class User implements Cloneable{
private String name;
private String sex;
@Max(value=10,message = "年龄不能超过10岁。")
private int age;
private Address address;
@Override
public Object clone(){
User user = null;
try{
user = (User)super.clone();
}catch (CloneNotSupportedException e){
System.out.println(e.getMessage());
}
user.address = (Address)address.clone();
return user;
}
}
调用方法:
Address a = new Address();
a.setAddress("山东");
User user1 = new User();
user1.setAddress(a);
User user2 = (User)user1.clone();
a.setAddress("上海");
user2.setAddress(a);
System.out.println("user1.address="+user1.getAddress());--上海
System.out.println("user2.address="+user2.getAddress());--山东
工具类BeanUtils:浅拷贝
BeanUtils.copyProperties(元对象,目标对象);
User.java
@Data
public class User{
private String name;
private String sex;
@Max(value=10,message = "年龄不能超过10岁。")
private int age;
private Address address;
}
Address.java
@Data
public class Address{
private String address;
}
调用方法
@Test
public void stuCopyTest(){
Address a = new Address();
a.setAddress("山东");
User user1 = new User();
user1.setAddress(a);
user1.setAge(18);
User user2 = new User();
BeanUtils.copyProperties(user1,user2);
a.setAddress("上海");
user2.setAge(19);
System.out.println("user1.age="+user1.getAge()+"user1.address="+user1.getAddress());
System.out.println("user2.age="+user2.getAge()+"user2.address="+user2.getAddress());
}
返回结果:子对象没有实现完全copy
user1.age=18,user1.address=Address(address=上海)
user2.age=19,user2.address=Address(address=上海)