结合JVM解读浅拷贝和深拷贝 |
您所在的位置:网站首页 › java深拷贝和浅拷贝说法错误的是 › 结合JVM解读浅拷贝和深拷贝 |
java.lang.Cloneable和java.io.Serializable一样属于标记型接口,没有定义任何方法和属性。 ![]() 这里使用User、Phone举例。 测试浅拷贝、深拷贝所用的Main方法如下: public class CloneTest { public static void main(String[] args) throws CloneNotSupportedException { // 预置数据 Phone phone1 = new Phone(); String number = "11111111111"; phone1.setPhoneNum(number); String name = new String("dkangel"); int age = 24; User user1 = new User(name, age, phone1); User user2 = (User) user1.clone(); System.out.println("对象是否相等:" + (user1 == user2)); System.out.println("类的类型是否相等:" + (user1.getClass() == user2.getClass())); System.out.println("age属性是否相等:" + (user1.getAge() == user2.getAge())); System.out.println("name属性是否相等:" + (user1.getName() == user2.getName())); System.out.println("对象的对象属性Phone是否相等:" + (user1.getPhone() == user2.getPhone())); } } 浅拷贝只拷贝对象本身,Phone不需要实现Cloneable接口和重写clone()方法。 public class Phone { private String phoneNum; public String getPhoneNum() { return phoneNum; } public void setPhoneNum(String phoneNum) { this.phoneNum = phoneNum; } } public class User implements Cloneable { private String name; private int age; private Phone phone; public User(String name, int age, Phone phone) { this.name = name; this.age = age; this.phone = phone; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Phone getPhone() { return phone; } public void setPhone(Phone phone) { this.phone = phone; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }user2是user1的浅拷贝,只拷贝user1对象本身,未拷贝成员变量phone,所以两者phone对象相等 不仅拷贝对象本身,而且拷贝对象所指向的所有对象,所以Phone类也要支持clone。 public class Phone implements Cloneable{ private String phoneNum; public String getPhoneNum() { return phoneNum; } public void setPhoneNum(String phoneNum) { this.phoneNum = phoneNum; } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } }User.java 这里只粘贴clone()方法,其他和浅克隆保持一致 public class User implements Cloneable { @Override protected Object clone() throws CloneNotSupportedException { User user = (User) super.clone(); user.phone = (Phone) user.getPhone().clone(); return user; } }user2是user1的深拷贝,拷贝user1本身的同时也拷贝一份phone1对象,两者phone对象不再相等
模式下从上到下解读CloneTest的main方法,得出如下对象在JVM中的分布图。 这里采用句柄模式访问对象(还有直接地址模式),简单解读下 new出来的对象phone1存入堆的实例池里;字符串number由于使用引号创建,所以存到堆中的字符串常量池;字符串name使用new创建,所以存入String实例池;age属于基本数据类型所以存入虚拟机栈;user1在堆中分配内存,通过clone对象user1本身的数据创建对象user2,user2的属性name/age/phone都与user1共用。 通过深拷贝创建的user2,不再与user1对象共用phone属性。深拷贝不仅拷贝了user1本身,也拷贝了user1的phone1对象。 这里只粘贴了与浅拷贝不同的地方,user2的phone属性由指向phone1改为指向phone2 如若有错误还望不吝指出,peace |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |