java中的对象拷贝
来源:互联网 发布:ubuntu u盘挂载 编辑:程序博客网 时间:2024/06/04 01:14
java中clone()方法的的作用是Creates and returns a copy of this object。
The general intent is that, for any object {@code x}, the expression:
- x.clone() != x,will be true
- x.clone().getClass() == x.getClass(),will be true
- x.clone().equals(x),will be true 其中第一点必须是不等的,也就是说复制出来的对象有自己单独的内存地址;第二点表明clone出来的java对象的java类型是相同的,不是强制要求的;第三点表明clone出来的对象使用equals方法是相等的,但不是强制要求的。
下来我们来做个试验:
public class Student implements Cloneable{ private String name; private int age; private Address address; public Student(String name, int age, Address address) { this.name = name; this.age = age; this.address = address; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }}
public class Address { private String city; private String country; public Address(String city, String country) { this.city = city; this.country = country; }}
测试一下,是不是如我们jdk文档所说的
public class Test { public static void main(String[] args) throws CloneNotSupportedException { Address address = new Address("wuhan","china"); Student student = new Student("jack",25,address); Student cloneStuednt = (Student) student.clone(); System.out.println(student != cloneStuednt); System.out.println(student.getClass() == cloneStuednt.getClass()); System.out.println(cloneStuednt.equals(student)); }}输出:truetruefalse
如果这个时候我们更改原对象中的状态又会发生什么呢?
public class Test { public static void main(String[] args) throws CloneNotSupportedException { Address address = new Address("wuhan","china"); Student student = new Student("jack",25,address); Student cloneStuednt = (Student) student.clone(); student.getAddress().setCity("nanjing"); System.out.println(cloneStuednt.getAddress().getCity()); }}输出nanjing
我们会发现如果改变了原对象,那么克隆出来的对象也发生了变化,在某些情况下,我们并不希望这种事情发生。其实这是由于浅克隆造成的,那么如何可以避免浅克隆
deep clone
上面这个例子浅克隆的原因是由于Address对象没有实现Cloneable接口,如果Address对象也实现了这个接口,并重写了clone()方法,便可以解决这个问题。
public class Address implements Cloneable{ private String city; private String country; public Address(String city, String country) { this.city = city; this.country = country; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; }}
public class Student implements Cloneable{ private String name; private int age; private Address address; public Student(String name, int age, Address address) { this.name = name; this.age = age; this.address = address; } @Override protected Object clone() throws CloneNotSupportedException { Student clone = (Student) super.clone(); clone.setAddress((Address) clone.getAddress().clone()); return clone; } 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 Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; }}
最后我们再次运行一下测试类,会发现这次是我们所期望的结果
public class Test { public static void main(String[] args) throws CloneNotSupportedException { Address address = new Address("wuhan","china"); Student student = new Student("jack",25,address); Student cloneStuednt = (Student) student.clone(); student.getAddress().setCity("nanjing"); System.out.println(cloneStuednt.getAddress().getCity()); }}输出wuhan
这的确完成了deep clone,但我们并不推荐这样去做,在实际的项目中很可能也无法让每个类都去实现Cloneable接口重写clone方法。那么是否还有其他的方法可以完成深拷贝吗? apache的 org.apache.commons.lang.SerializationUtils类有一种方法,使用序列化和反序列化的方法实现了深拷贝。主要的代码是:
ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(object);oos.flush();oos.close();bos.close();byte[] byteData = bos.toByteArray();ByteArrayInputStream bais = new ByteArrayInputStream(byteData);(Object) object = (Object) new ObjectInputStream(bais).readObject();
这种方法我感觉应该是最简单的方法实现深拷贝的方法。
另外还有另外一种方法实现了深拷贝,通过java反射区一个个去get/set设置java对象。
阅读全文
0 0
- Java中的对象拷贝
- java中的对象拷贝
- Java 开发中的对象拷贝
- 谈谈Java开发中的对象拷贝
- python中的对象拷贝
- java拷贝对象
- Java对象拷贝
- JAVA对象拷贝
- JAVA 对象拷贝
- Java深拷贝对象
- java深浅对象拷贝
- java对象拷贝
- java对象拷贝
- JAVA 对象拷贝
- java-对象拷贝
- Java对象深拷贝
- Java 对象拷贝
- JAVA 对象拷贝
- Python XML解析
- 如何快速搭建一个完整的移动直播系统?
- javascript面向对象——面向对象基础
- Android内存泄漏检测工具
- C# hashtable、dictionary、list的差异
- java中的对象拷贝
- Android 动态设置列表样式,不用ListView或者RecyclerView
- [源码阅读笔记]Zhihu-OAuth
- Spinner库
- 1.7 指针和引用
- 线性序列 模版
- (POJ
- JavaScript闭包详解
- GET请求jsonp示例