【Java基础】对象拷贝
2016-07-02 23:37
453 查看
背景
如果不关注对象引用传递,这必将带来的是悲剧,你将一个对象从一个模块交到了另一个模块而浑然不知,而当另一个模块在修改该对象的内容同时也默默的影响到之前的模块,这是很糟糕的,问题也很难找。我们如何在编码中警觉到这一点?
我们如何在编码中警觉到这一点?以减少最后成为这种问题的受害者时候的尴尬呢?准则一:B模块需要使用到A模块中的某对象值,B模块内对该对象值修改,你期望这会影响到A模块的该对象内容吗?如果否,那就请用对象拷贝。一般为否。
准则二:当你的模块对外暴露方法接口提供对象,如果外界修改该对象内容,你期望这会影响到你自身模块的该对象内容吗?如果否,那就请用对象拷贝。一般为否。
对象拷贝
浅拷贝
拷贝对象自身,但不拷贝对象内所引用的对象class Student implements Cloneable { public int age; public String name; public Teacher teacher; /** * 重写clone()方法 * @return */ public Object clone() { //浅拷贝 try { // 直接调用父类的clone()方法 return super.clone(); } catch (CloneNotSupportedException e) { return null; } } }
深拷贝
除了拷贝对象自身,连同对象内所引用的对象也进行拷贝一.嵌套clone方式
接上面浅拷贝,在自身对象clone执行的时候,也嵌套执行所引用对象的clone方法,并将clone对象设置到自身对象中。@Override public Object clone() throws CloneNotSupportedException { Student student = (Student) super.clone(); // 将引用的对象teacher也clone下 student.setTeacher((Teacher) (student.getTeacher().clone())); return student; }
二.序列化方式
/** * 深度拷贝 要求data对象及引用对象都实现了Serializable接口才可以用 * @param data */ public static <T> T deepCopy(T data) throws Exception { // 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(data); // 将流序列化成对象 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return (T) ois.readObject(); }
对比
从实现角度而言,方式二更加简便,只需要实现Serializable,方式一,需要实现了Cloneable,还有clone方法。效率还不知道。相关文章推荐
- java程序与java WEB的区别
- spring容器与管理bean的生命周期
- springMVC_后台自动接受map数据
- JAVA中使用POST和GET发送请求
- 设计模式六大原则
- springmvc中的处理模型数据
- MyBatis基于Java API配置
- spring注解方式配置AOP
- java抽象工厂模式(Abstract Factory)-创建型
- java串口通信API说明
- Spring4.* 中整合 Hibernate
- 统计一个字符串中单个字符出现的次数
- 编程珠玑第五章二分搜索(折半查找)之java实现
- java中PreparedStatement接口及ResultSet结果集
- Spring MVC @ModelAttribute详解
- Java基础之(四) this的用法
- Java Web 获取项目路径
- springmvc 结合 ehcache
- java框架之springmvc06(数据验证)
- JAVA 多态-深层次理解