Java对象的复制方式
Java对象的复制方式
场景
在实际编程中需要两个相互独立的对象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());--上海 <、pre> 此时,子对象并未被真正复制。想要真正复制,需要将子类的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; } } <、pre> 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; } } <、pre> 调用方法: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());--山东 <、pre> 工具类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; } <、pre> Address.java@Data public class Address{ private String address; } <、pre> 调用方法@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=上海)