- 浏览: 1230684 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
lankk:
lankk 写道事实上,在运行String s1=new St ...
理解String 及 String.intern() 在实际中的应用 -
lankk:
事实上,在运行String s1=new String(&qu ...
理解String 及 String.intern() 在实际中的应用 -
lankk:
同意1楼的说法http://docs.oracle.com/j ...
理解String 及 String.intern() 在实际中的应用 -
raoyutao:
...
jdk 线程池 ThreadPoolExecutor -
hongdanning:
理解了。之前困惑的一些明白了。谢谢分享。
理解String 及 String.intern() 在实际中的应用
本以为这个方法可以方便的clone对象,但写了下测试用例,发现不是
by the way 我用的是commons-beanutils-1.8.2.jar 和 Junit3.jar ,最开始少jar
要commons-logging.jar,看下官网
The commons-beanutils package requires that the following additional packages be available in the application's class path at runtime: Logging Package (Apache Commons), version 1.0 or later Furthermore, if any of the following commons-beanutils classes are used: org.apache.commons.beanutils.BeanMap org.apache.commons.beanutils.BeanPredicate org.apache.commons.beanutils.BeanPropertyValueChangeClosure org.apache.commons.beanutils.BeanPropertyValueEqualsPredicate org.apache.commons.beanutils.BeanToPropertyValueTransformer then the following packages must also be available in the application's class path at runtime: Collections Package (Apache Commons), version 1.0 or later
Teacher类
package clone; public class Teacher { private String name; public Teacher(String name) { super(); this.name = name; } public Teacher() { } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Class类
package clone; public class Class { private int num; private Teacher sir; public Class(int num, Teacher sir) { super(); this.num = num; this.sir = sir; } public Class() { } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public Teacher getSir() { return sir; } public void setSir(Teacher sir) { this.sir = sir; } }
测试用例
package clone; import junit.framework.TestCase; import org.apache.commons.beanutils.BeanUtils; public class Test extends TestCase { public void testClone() throws Exception { Teacher sir = new Teacher("sir1"); Class c = new Class(1, sir); Class c2 = (Class) BeanUtils.cloneBean(c); System.out.println(c.getSir() == c2.getSir()); assertNotSame(c, c2); assertSame(c.getSir(), c2.getSir()); c.getSir().setName("xx"); assertEquals(c2.getSir().getName(), "xx"); System.out.println("clone is not deep"); } public void testClone2() throws Exception { Teacher sir = new Teacher("sir1"); Class c = new Class(1, sir); Teacher sir2 = (Teacher) BeanUtils.cloneBean(c.getSir()); Class c2 = new Class(); BeanUtils.copyProperties(c2, c); c2.setSir(sir2); assertNotSame(c, c2); assertNotSame(c.getSir(), c2.getSir()); c.getSir().setName("xx"); assertFalse(c2.getSir().getName().equals("xx")); System.out.println("clone is deep"); } }
用例改成了最后能够pass的,
BeanUtils.cloneBean() 在源码上看是调用了 getPropertyUtils().copyProperties(newBean, bean);
最后实际上还是复制的引用 ,所以第一个方法无法实现深clone
但BeanUtils还是可以帮助我们减少工作量的,假如类的属性不是基础类型的话(即自定义类),可以先clone出那个自定义类,在把他付给新的类,覆盖原来类的引用,具体做法见第二个测试方法,
不过假如对象自定义类属性多,级别深的话,这样还是很麻烦
在teacher class类上面都写了一个默认的clone方法后
@Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub return super.clone(); }
我又写了个测试方法 和第2个基本一样
public void testClone3() throws Exception { Teacher sir = new Teacher("sir1"); Class c = new Class(1, sir); Teacher sir2 = (Teacher) c.getSir().clone(); Class c2 = (Class) c.clone(); c2.setSir(sir2); assertNotSame(c, c2); assertNotSame(c.getSir(), c2.getSir()); c.getSir().setName("xx"); assertFalse(c2.getSir().getName().equals("xx")); System.out.println("clone is deep"); }
pass
看来BeanUtils.cloneBean()是为那些本身没有实现clone方法的类准备的
还有一种序列化的方法 这种方法要求所有属性 对象都是实现了序列化接口
package com.test3; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; //利用序列化来做深复制 //深clone public class DeepCloneTest { public static void main(String[] args) throws Exception{ //teacher对象将不被clone出来的Student对象共享. Teacher teacher = new Teacher(); teacher.setAge(40); teacher.setName("Teacher zhang"); Student student1 = new Student(); student1.setAge(20); student1.setName("zhangsan"); student1.setTeacher(teacher); //复制出来一个对象student2 Student student2 = (Student)student1.deepCopy(); System.out.println(student2.getAge()); System.out.println(student2.getName()); System.out.println("~~~~~~~~~~~~~~~~~~~~~~"); System.out.println(student1.getTeacher().getAge()); System.out.println(student1.getTeacher().getName()); //修改student2的引用对象 student2.getTeacher().setAge(50); student2.getTeacher().setName("Teacher Li"); System.out.println("~~~~~~~~~~~~~~~~~~~~~~"); System.out.println(student1.getTeacher().getAge()); System.out.println(student1.getTeacher().getName()); } } class Teacher implements Serializable{ private static final long serialVersionUID = -8834559347461591191L; public int age; public String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } } class Student implements Serializable{ //serialVersionUID 如果你的对象序列化后存到硬盘上面后,可是后来你却更改了类的field(增加或减少或改名),当你反序列化时,就会出现Exception的,这样就会造成不兼容性的问题。 //但当serialVersionUID相同时,它就会将不一样的field以type的缺省值赋值(如int型的是0,String型的是null等),这个可以避开不兼容性的问题。所以最好给serialVersionUID赋值 private static final long serialVersionUID = 7991552226614088458L; public int age ; public String name; public Teacher teacher; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Teacher getTeacher() { return teacher; } public void setTeacher(Teacher teacher) { this.teacher = teacher; } public Object deepCopy() throws Exception{ //将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); //将流序列化成对象 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return ois.readObject(); } } 输出结果为: 20 zhangsan ~~~~~~~~~~~~~~~~~~~~~~ 40 Teacher zhang ~~~~~~~~~~~~~~~~~~~~~~ 40 Teacher zhang
评论
2 楼
Nightlee
2009-12-18
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import org.apache.commons.beanutils.BeanUtils; public class M1 { public static void main(String[] args) throws Throwable { C1 o1 = new C1(); o1.setP1(new C1()); C1 o2 = (C1) BeanUtils.cloneBean(o1); System.out.println(o1.getP1() == o2.getP1()); C1 o3 = (C1) deepClone(o1); System.out.println(o1.getP1() == o3.getP1()); } public static Object deepClone(Object src) throws Throwable { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(src); oos.close(); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); Object o = ois.readObject(); ois.close(); return o; } public static class C1 implements Serializable { C1 p1; public C1 getP1() { return p1; } public void setP1(C1 p1) { this.p1 = p1; } } }
1 楼
Nightlee
2009-12-18
BeanUtils本来就是属性copy,深copy用对象串行化的方法吧
发表评论
-
大型网站技术架构 读书笔记
2017-11-29 14:17 1313web 前端 优化 浏览器 减少http请求 合并c ... -
业务unique ID的生成策略分析
2017-02-20 16:31 1011业务unique ID的生产策略分析 需求上 ... -
ServiceLocatorFactoryBean 学习
2016-01-27 14:36 3386今天看一个新项目 ... -
用户注册流程的一个好列子
2015-05-06 15:42 1260最近用了一个app, 《不背单词》, 里面的用户注册很有意 ... -
jvm notes
2014-12-16 15:19 1689运行时数据区 program counter re ... -
window server 2008 task 不执行问题
2014-01-24 10:53 3927要在win2008下设置一个定时任务, .bat执行的任务, ... -
(转)date format
2013-12-04 13:40 1195深入理解Java:SimpleDateFormat安全 ... -
POI excel 触发 公式 计算 删除空白行
2013-04-15 12:44 5084用POI api修改excel 表格数据后, 想触发计算公式 ... -
java 汉字 \u 转换
2012-08-08 13:32 2277import org.apache.c ... -
地址解析api资源
2011-06-28 10:50 1471Search for location What you ... -
cvs 查看个人提交记录
2011-06-23 11:25 8796eclipse的cvs插件不能看自己在整个项目的提交历史 但 ... -
html5 学习笔记
2011-06-13 18:32 1427基本 <!doctype html> & ... -
twitter 新 share url
2011-05-27 10:39 1182http://twitter.com/intent/tweet ... -
linkedin share
2011-05-26 16:47 1549分享的时候linkedin 也是去url上抓取信息的 但他和 ... -
facebook share
2011-05-25 20:49 1932通过url share到facebook时 是由faceb ... -
php 字符串 包含 比较 替换
2010-08-30 20:56 5244if(strpos($str, 'ok') !== fals ... -
查看 http 请求
2010-05-25 19:34 1268httpdebugerpro -
evernote 太强大了
2010-03-10 15:42 2074在PC MAC IPHONE ANDROID 上面都有客户端, ... -
open command window here, window xp下的一个好工具
2010-03-09 11:07 1462发现一个windows下的工具,可以让你对着一个文件夹,右键, ... -
用批处理设置jdk和tomcat环境变量
2010-03-05 17:26 2523学过Java编程的人应该知道,都是要设置JDK的环境变量,这个 ...
相关推荐
一个BeanUtils.copyProperties的小型快速替代。 起因 由于BeanUtils(Spring或Apache Commons)的copyProperties实现是利用反射实现的,它在大量调用时具有比较严重的性能问题。 BeanMapper通过javassist类库实现在...
《JSF中的commons-beanutils.jar:深入了解与应用》 在Java Server Faces(JSF)框架的开发过程中,经常会遇到一些常用的库文件,其中之一便是`commons-beanutils.jar`。这个小巧却强大的库,是Apache Commons项目...
httpclient 开发依赖的jar。 主要 org.apache.commons.beanutils.jar
commons-beanutils-1.8.0.jar beanutils.jar beanutils.jar工具包
commons-beanutils.jar commons-beanutils.jar
标题中的"commons-beanutils.jar"就是这个库的实现文件,用于简化JavaBean对象的属性操作。当我们在处理JSON数据并尝试将这些数据绑定到Java对象时,可能会遇到因缺少这个库而导致的问题。 首先,Apache Commons ...
json相关jar包(不使用springmvc开发时)。其中包含(commons-beanutils.jar、commons-collections-3.1.jar、commons-lang-2.6.jar、commons-logging.jar、ezmorph-1.0.6.jar、json-lib-2.2.3-jdk15.jar)
此为BeanUtils的实例。其中apache的包有一个小的BUG已在其中说明。
Apache提供的这个beanutils包极大方便了javabean的 操作。包含了最新的commons-beanutils-1.9.3.jar和api文档,以及其依赖的commons-logging-1.2.jar包
标题中的"commons.jar +commons-beanutils.jar"指的是Apache Commons项目中的两个核心组件:commons.jar和commons-beanutils.jar。Apache Commons是Java编程语言中的一系列小型实用程序库,为开发人员提供了各种常见...
beanUtils 方便访问javaBean 附带支持框架 logging jar包,Apache提供的这个beanutils包极大方便了javabean的 操作。包含了最新的commons-beanutils-1.9.3.jar,以及其依赖的commons-logging-1.2.jar包
JSF开发所必需包:花了很长时间才收集好,很费时,现已收集好,何不分享给大家,让大家节省...commons-beanutils.jar commons-collections.jar commons-digester.jar jsf-api.jar jsf-impl.jar jstl.jar standard.jar
commons-beanutils.jar.zip(173 k)commons-beanutils.jar.zip(173 k)commons-beanutils.jar.zip(173 k) jdbc 专用
- **嵌套对象属性**:`BeanUtils.getProperty(orderBean, "address.city")`。此例中,`orderBean`中包含一个名为`address`的属性,而`address`又包含一个名为`city`的属性。通过使用点分隔符,可以直接获取`city`的...
Java Beanutils.copyProperties() 用法详解 Java Beanutils.copyProperties() 方法是 Java 中一个非常有用的工具,主要用于将一个 JavaBean 的属性复制到另一个 JavaBean 中。今天,我们将详细介绍 Java Beanutils....