在研究对象拷贝属性的时候,踩了坑,特此记录一下。
一、使用BeanUtils.copyProperties(A,B)的时候,特别需要注意
有两个包都存在该方法,并且两个方法的参数不一致
org.apache.commons.beanutils.BeanUtils包
BeanUtils.copyProperties(dest, orig);
是由orig对象拷贝到dest对象中,也就是从B拷贝到A
org.springframework.beans.BeanUtils包
BeanUtils.copyProperties(source, target);
是有source对象拷贝到target对象中,也就是从A拷贝到B
这是第一个坑,不过,稍微有点经验的都应该知道,重点是第二个坑。
二、使用org.apache.commons.beanutils.BeanUtils工具进行转换时,一直不能成功
如图:
由于第一次尝试的时候,是直接在一个JAVA类中编写的
工具方法和类全部写在同一个文件中,由于一个java源文件中只能有一个public的类
所以,其他类均未采用public修饰 此处为背景
跟踪源码
在调试过程中发现,getPropertyUtils().isReadable(orig,name)返回了false
断点进入,的确返回false
readMethod值来源于getReadMethod(bean.getClass(),desc)
进入方法,797行处执行,返回false 说明该class不包含public修饰
后续执行,返回null
返回null,运行到如下代码
进入方法,第一步中,直接return (null)
再次返回到上一个方法中,null!=null值是false
经过分析,怀疑是权限问题,将Class A前面加上public修饰后,再次调试
方法内容,返回true
断点调试,进入其中,此时Modifier.isPublic返回true了
进入if内部,此时method不为空了
所以,成功进入方法内部,成功调用拷贝方法
最终,拷贝成功
一般来说,创建的Class肯定会使用public修饰,但是全部写在同一个文件中时,且使用的apache的工具包时,就会出现这种拷贝不成功的情况。
使用springframework的工具包时,及时类名未添加public修饰,也能拷贝成功
其中两个if都未进入,Modifier返回的结果是true,!true即是false
均为影响invoke方法执行,采用反射方式拷贝属性值
结论:
apache工具的底层源码,会判断class的访问权限
springframework工具的底层源码,直接使用反射,访问权限不影响
如果要使用BeanUtilsBean.copyProperties方法,要么使用springframework包的,要么Class使用public修饰。
还没有评论,来说两句吧...