- 浏览: 216687 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
zi_wu_xian:
顶5楼,POI操作word和excel还是太复杂了,并且针对d ...
使用POI操作Excel和Word -
贝塔ZQ:
poi操作word、excel代码好多啊,用插件试试吧,网上不 ...
使用POI操作Excel和Word -
wap816:
@CacheEvict(value = ...
SpringEL详解及应用 -
string2020:
List<Map<String,Map<St ...
开源工具 — Apache Commons Collections -
uniqueX:
mark!
并发编程 — 判断线程安全
开源工具系列文章:
Apache Commons Lang(1):http://ray-yui.iteye.com/blog/1953020
Apache Commons Lang(2):http://ray-yui.iteye.com/blog/1958319
Apache Commons BeanUtils:http://ray-yui.iteye.com/blog/1961451
Apache Commons Collections:http://ray-yui.iteye.com/blog/2021484
Apache Commons IO:http://ray-yui.iteye.com/blog/2023034
在笔者之前的文章提到过,在BeanUtils中通过PropertyUtils取代了FieldUtils,PropertyUtils是一套很容易操作类属性的API工具类,使用非常简单而且保持了对类的封装,使用get和set进行存取
public class TestMain { public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { // 初始化信息 Test test = new Test(); Integer[] testArray = new Integer[10]; Map<String, String> testMap = new HashMap<String, String>(); // 以下方法名为set开始的方法均有get方法与其对应 // 设置username,testArray,testMap属性 PropertyUtils.setProperty(test, "username", "Hello"); PropertyUtils.setProperty(test, "testArray", testArray); PropertyUtils.setProperty(test, "testMap", testMap); // 设置testArray属性下标为0的值为10 PropertyUtils.setIndexedProperty(test, "testArray[0]", 10); // 设置testMap属性的值为参数三,遗憾是 key参数只支持字符串 PropertyUtils.setMappedProperty(test, "testMap", "Hello", "10"); // 在类中有嵌套类的时候,就不能使用简单的setProperty来对引用类设置属性, // 要使用nested,address为test类中属性名引用 PropertyUtils.setNestedProperty(test, "address.id", 1); // 判断属性是否有get方法或set方法 PropertyUtils.isReadable(test, "username"); PropertyUtils.isWriteable(test, "username"); // 返回该实例全部属性,属性名为key,值为value Map<String, Object> map = PropertyUtils.describe(test); // 把test对象的所有属性复制到test2对象当中, // 通过反射字段名匹配进行复制,但要注意将会覆盖原值 Test test2 = new Test(); PropertyUtils.copyProperties(test2, test); // 获取属性的Class类型 PropertyUtils.getPropertyType(test, "username"); } }
PropertyUtils和BeanUtils的方法非常相似,但有一些小细节上可以区别它们,例如都使用copyProperty,BeanUtils只要属性名一致就算类型不同都可以互相兼容赋值,但PropertyUtils则会报错
public class TestMain { public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException { Test test1 = new Test(); Test test2 = new Test(); // 复制单个属性 BeanUtils.copyProperty(test1, "username", test2); // 克隆对象,注意是浅克隆 Test test3 = (Test) BeanUtils.cloneBean(test1); /* * 在设置时间时,读者需要注意一个小问题, * 用-->setProperty(test1, "date", new Date()); * 这种方式设置时间时没有问题的,但若然使用字符串的形式2013-10-3 * 就会出现问题,这是因为BeanUtils无法识别字符串类型和时间类型的关系, * 所以我们需要使用ConvertUtils来辅助BeanUtils, * 但使用如下方式进行转换后,PropertyUtils仍然是无能为力 */ //用此种方式没任何问题 BeanUtils.setProperty(test1, "date", new Date()); //此种方式无法区别字符串还是日期 BeanUtils.setProperty(test1, "date", "2013-10-01"); // 自定义一个转换器 ConvertUtils.register(new Converter() { @Override public Object convert(Class type, Object value) { if (value == null) { throw new RuntimeException("value is null"); } if (value.getClass() == Date.class) { return value; } if (value.getClass() != String.class) { throw new RuntimeException("type not match"); } String valueStr = (String) value; if (StringUtils.isBlank(valueStr)) { throw new RuntimeException("string is empty"); } try { return new SimpleDateFormat("yyyy-MM-dd").parse(valueStr); } catch (ParseException e) { e.printStackTrace(); return null; } } }, Date.class); // 此时使用字符串的日期形式都可以成功转换 BeanUtils.setProperty(test1, "date", "2013-10-1"); } }
从上面时间转换的例子就能看出,为什么同属性名不同类型PropertyUtils会转换失败,因为PropertyUtils并没有使用ConvertUtils来进行转换,导致类型不同时没发互相转换,由于Apache commons发展历史的原因,导致某些Utils功能大致相同,请读者自行选择
在某些业务情况下,我们的Bean是不确定的,可能随某些地方触发而改变,可能需要某个属性,又可能不需要某个属性,这种动态的Bean是编译性语言的Java无法支持的,但BeanUtils中的自由Bean(动态Bean)将动态创建Bean成为了可能
public class TestMain { public static void main(String[] args) throws IllegalAccessException, InstantiationException { // 创建动态Bean所拥有的字段 DynaProperty[] props = new DynaProperty[] { new DynaProperty("id", String.class), new DynaProperty("testMap", Map.class) }; // 创建dynaClass的BasicDynaClass实现,传入定义的props DynaClass dynaClass = new BasicDynaClass("bean", null, props); // 通过dynaClass创建Bean DynaBean bean = dynaClass.newInstance(); // 可以按普通bean的方式对其进行使用 bean.set("id", "hello"); bean.set("testMap", new HashMap()); bean.set("testMap", "Hello", "World"); bean.get("id"); bean.get("testMap", "Hello"); /* * BasicDynaClass是DynaClass接口的实现类, * 其中还有LazyDynaClass的实现可以帮助我们更方便 * 的使用动态bean,lazy,懒嘛!方便 */ // 不需要再定义dynaProperty,直接赋值时将会自动声明属性 DynaClass dynaClass = new LazyDynaClass(); DynaBean dynaBean = dynaClass.newInstance(); dynaBean.set("username", "Hello"); dynaBean.set("testArray", 0, "Hello"); dynaBean.set("testMap", "Hello", "World"); dynaBean.get("username"); dynaBean.get("testArray", 0); dynaBean.get("testMap", "Hello"); } }
总结:
commons工具包很多开源组织都有提供,例如google,spring,apache都有各自的工具包,有众多的选择,但最终的目的只是为了方便我们程序的开发和维护,简化我们编写一些常用的逻辑,提升我们开发的效率,从而达到活在开源,善用开源
评论
4 楼
ray_yui
2013-10-22
ping2010 写道
ping2010 写道
// 克隆对象,注意是深克隆,非常有用
Test test3 = (Test) BeanUtils.cloneBean(test1);
这句话不对,根本不是深度复制。
Test test3 = (Test) BeanUtils.cloneBean(test1);
这句话不对,根本不是深度复制。
package org.runant.demo ; import org.apache.commons.beanutils.BeanUtils; /* * $Id:testClone.java * * Copyright (C) 2000-2013 Runant Systems, Inc, see http://www.runant.org. * All rights reserved * * Created by Runant on 2013-10-22 */ public class testClone { /** * @param args */ public static void main(String[] args) throws Exception { Address address = new Address("SZ", 101000); User user = new User("GoodBoy", "123456", address); User target = (User) BeanUtils.cloneBean(user); System.out.println(target.getPassword()); Address targetAddress = target.getAddress(); targetAddress.setDetail("BJ"); System.out.println("oraginal address:" + address + ",clone address:" + targetAddress); System.out.println("oraginal address:" + address.getDetail() + "," + address.getNum()); System.out.println("clone address:" + targetAddress.getDetail() + "," + targetAddress.getNum()); } public static class User { public User() { } public User(String userName, String password, Address address) { this.userName = userName; this.password = password; this.address = address; } private String userName; private String password; private Address address; public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } public static class Address { public Address() { } public Address(String detail, Integer num) { this.detail = detail; this.num = num; } private String detail; private Integer num; public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } public Integer getNum() { return num; } public void setNum(Integer num) { this.num = num; } } }
执行的结果为:
123456
oraginal address:testClone$Address@16897b2,clone address:testClone$Address@16897b2
clone address:BJ,101000
oraginal address:BJ,101000
非常感谢你的提醒,已修改
3 楼
ping2010
2013-10-22
ping2010 写道
// 克隆对象,注意是深克隆,非常有用
Test test3 = (Test) BeanUtils.cloneBean(test1);
这句话不对,根本不是深度复制。
Test test3 = (Test) BeanUtils.cloneBean(test1);
这句话不对,根本不是深度复制。
package org.runant.demo ; import org.apache.commons.beanutils.BeanUtils; /* * $Id:testClone.java * * Copyright (C) 2000-2013 Runant Systems, Inc, see http://www.runant.org. * All rights reserved * * Created by Runant on 2013-10-22 */ public class testClone { /** * @param args */ public static void main(String[] args) throws Exception { Address address = new Address("SZ", 101000); User user = new User("GoodBoy", "123456", address); User target = (User) BeanUtils.cloneBean(user); System.out.println(target.getPassword()); Address targetAddress = target.getAddress(); targetAddress.setDetail("BJ"); System.out.println("oraginal address:" + address + ",clone address:" + targetAddress); System.out.println("oraginal address:" + address.getDetail() + "," + address.getNum()); System.out.println("clone address:" + targetAddress.getDetail() + "," + targetAddress.getNum()); } public static class User { public User() { } public User(String userName, String password, Address address) { this.userName = userName; this.password = password; this.address = address; } private String userName; private String password; private Address address; public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } public static class Address { public Address() { } public Address(String detail, Integer num) { this.detail = detail; this.num = num; } private String detail; private Integer num; public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } public Integer getNum() { return num; } public void setNum(Integer num) { this.num = num; } } }
执行的结果为:
123456
oraginal address:testClone$Address@16897b2,clone address:testClone$Address@16897b2
clone address:BJ,101000
oraginal address:BJ,101000
2 楼
ping2010
2013-10-22
// 克隆对象,注意是深克隆,非常有用
Test test3 = (Test) BeanUtils.cloneBean(test1);
这句话不对,根本不是深度复制。
Test test3 = (Test) BeanUtils.cloneBean(test1);
这句话不对,根本不是深度复制。
package org.runant.demo ; import org.apache.commons.beanutils.BeanUtils; /* * $Id:testClone.java * * Copyright (C) 2000-2013 Runant Systems, Inc, see http://www.runant.org. * All rights reserved * * Created by Runant on 2013-10-22 */ public class testClone { /** * @param args */ public static void main(String[] args) throws Exception { Address address = new Address("SZ", 101000); User user = new User("GoodBoy", "123456", address); User target = (User) BeanUtils.cloneBean(user); System.out.println(target.getPassword()); Address targetAddress = target.getAddress(); targetAddress.setDetail("BJ"); System.out.println("oraginal address:" + address + ",clone address:" + targetAddress); System.out.println("oraginal address:" + address.getDetail() + "," + address.getNum()); System.out.println("clone address:" + targetAddress.getDetail() + "," + targetAddress.getNum()); } public static class User { public User() { } public User(String userName, String password, Address address) { this.userName = userName; this.password = password; this.address = address; } private String userName; private String password; private Address address; public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } public static class Address { public Address() { } public Address(String detail, Integer num) { this.detail = detail; this.num = num; } private String detail; private Integer num; public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } public Integer getNum() { return num; } public void setNum(Integer num) { this.num = num; } } }
1 楼
liushicheng1
2013-10-21
系列文章写的很不错
发表评论
-
开源工具 — Apache Commons IO
2014-02-27 09:32 5120开源工具系列文章: Apache Commons ... -
开源工具 — Apache Commons Collections
2014-02-25 10:09 4652开源工具系列文章: Apache Commons ... -
开源工具 — Apache Commons Lang(2)
2013-10-15 11:22 9146开源工具系列文章: Apache Commons ... -
开源工具 — Apache Commons Lang(1)
2013-10-08 09:45 6929开源工具系列文章: Apache Commons ...
相关推荐
org.apache.commons的jar包,Apache Commons包含了很多开源的工具。 包括commons-beanutils-1.8.0-bin、commons-betwixt-0.8、commons-cli-1.1、commons-codec-1.3、commons-collections-3.2.1-bin、commons-...
commons-beanutil开源库是apache组织的一个基础的开源库。为apache中很多类提供工具方法。学习它是学习其它开源库实现的基础。 Commons-beanutil中包括大量和JavaBean操作有关的工具方法,使用它能够轻松利用Java...
commons-beanutils-1.8.3。commons-beanutils是Apache开源组织提供的用于操作JAVA BEAN的工具包。使用commons-beanutils,我们可以很方便的对bean对象的属性进行操作。
commons-beanutils是Apache开源组织提供的用于操作JAVA BEAN的工具包。使用commons-beanutils,我们可以很方便的对bean对象的属性进行操作
commons-beanutils.jar 免费下载 commons-beanutils 是 Apache 开源组织提供的用于操作 JAVA BEAN 的工具包。 使用 commons-beanutils,我们可以很方便的对 bean 对象的属性进行操作。
commons-beanutils是Apache开源组织提供的用于操作JAVA BEAN的工具包。使用commons-beanutils,我们可以很方便的对bean对象的属性进行操作。
commons-beanutils.jar 免费下载 commons-beanutils 是 Apache 开源组织提供的用于操作 JAVA BEAN 的工具包。 使用 commons-beanutils,我们可以很方便的对 bean 对象的属性进行操作。
Apache Commons包含了很多开源的工具,用于解决平时编程经常会遇到的问题,减少重复劳动。 包含的组件有BeanUtils、Codec、Collections、Lang、IO、FileUpLoad等等。本文档 帮助Java开发者学习相关内容
Bean Query 复用Apache Commons BeanUtils, Apache Commons Collections和Java Hamcrest 来简化对Bean(集合)的排序,过滤和转换。 文档 阅读 使用说明来学习怎么使用 BeanQueryExample.java用Junit...
Apache Commons包中的一个,包含了一些Bean工具类类。必须使用的jar包。 commons-collections.jar Apache Commons包中的一个,包含了一些Apache开发的集合类,功能比java.util.*强大 commons-lang.jar Apache ...
1.commons-beanutils.jar...12.commons-DbUtils.jar:Apache组织提供的一个资源JDBC工具类库,它是对JDBC的简单封装,对传统操作数据库的类进行二次封装,可以把结果集转化成List。 13.commons-Email.jar: 提供开源的API
Commons项目()的Logging和Beanutils软件包。 这些软件包的许可条款位于此目录中名为“ LICENSE.apache20”的文件中。 该软件使用Google Guava库()。 这些软件包的许可条款位于此目录中名为“ LICENSE.apache20”...
1,Apache.commons 1.1,beanutils propertyUtils类副本与反射副本使用及效率比较。 1.2,收藏CollectionUtils从一个列表中查找符合一定条件的对象。 2,太阳 2.1,发送邮件javax.mail完成邮件的发送和接收。 3,...