Java克隆技术
前些天,根据需要,加入了克隆技术,学习了下,总结如下:
Java的对象都是引用,当将一个对象赋值给另外一个对象的时候,也就是说指针(当然,java没有指针的概念)同指向同一块内存地址,这个时如果对一个对象进行修改,也必然会修改另外一个对象的值,这明显不是我们想要的,解决这个问题,可以引入克隆技术,我们可以克隆一个对象出来,使得对克隆出来的对象修改不会改变原始对象的值。
克隆分为:浅克隆和深克隆。
浅克隆是指:浅克隆只是克隆当前的对象,不克隆该对象所应用的对象
深克隆是指:深克隆不但克隆当前的对象,而且还克隆该对象所引用的对象
看具体实例:
(模拟场景:用户对象、地址对象、用户对象拥有地址对象)
一、浅克隆
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | //克隆必须实现Cloneable,调用父类的clone()方法 public class User implements Cloneable{ private String userName; private Address address; public User(String userName) { super (); this .userName = userName; } public String getUserName() { return userName; } public void setUserName(String userName) { this .userName = userName; } public Address getAddress() { return address; } public void setAddress(Address address) { this .address = address; } /* * 克隆当前对象,得到克隆后的对象 * @see java.lang.Object#clone() */ @Override public Object clone() throws CloneNotSupportedException { return super .clone(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | //地址对象 public class Address{ private String addressName; public Address(String addressName) { super (); this .addressName = addressName; } public String getAddressName() { return addressName; } public void setAddressName(String addressName) { this .addressName = addressName; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /** * 测试克隆-浅克隆 * 浅克隆只是克隆当前的对象,不克隆该对象所应用的对象 * @author CST */ public class TestClone { public static void main(String[] args) throws CloneNotSupportedException { User chen = new User( "CST" ); chen.setAddress( new Address( "福州" )); User liu = (User) chen.clone(); liu.setUserName( "LXF" ); liu.getAddress().setAddressName( "泉州" ); System.out.println(chen.getUserName()+ "=" +chen.getAddress().getAddressName()); } } |
输出结果:CST=泉州
可以看到,虽然User对象可以单独操作,但是视图去修改User下的Address值,仍然是改变了原始用户下的Address值
二、深克隆:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | public class User implements Cloneable{ private String userName; private Address address; public User(String userName) { super (); this .userName = userName; } public String getUserName() { return userName; } public void setUserName(String userName) { this .userName = userName; } public Address getAddress() { return address; } public void setAddress(Address address) { this .address = address; } //克隆 @Override public Object clone() throws CloneNotSupportedException { //克隆对象的同时,也克隆user下的应用对象Address User user = (User) super .clone(); Address address = (Address) user.getAddress().clone(); user.setAddress(address); return user; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public class Address implements Cloneable{ private String addressName; public Address(String addressName) { super (); this .addressName = addressName; } public String getAddressName() { return addressName; } public void setAddressName(String addressName) { this .addressName = addressName; } @Override protected Object clone() throws CloneNotSupportedException { return super .clone(); } } |
测试类同上,
输出结果:CST=长乐
这样,才是我们想要的结果。无论修改当前对象还是当前对象所包含的对象,都是两个独立的操作,互不影响。