`
hp9016
  • 浏览: 20106 次
  • 性别: Icon_minigender_1
  • 来自: 大连
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

BeanUtils.copyProperties在一个java源文件有多个类的情况下失败的原因

阅读更多
最近在copybean时,无意中遇到一个问题,一个java源文件中存在几个类的情况下,BeanUtils.copyProperties不能成功,整理如下,供大家探讨。

情况1(copy失败)、(一个java源文件中存在3个类),如下:

BeanCopy.java
package com.hp9016.test.copyBean;

import java.lang.reflect.InvocationTargetException;

import org.apache.commons.beanutils.BeanUtils;

public class BeanCopy {

    public static void main( String[] args ) {
        BeanFrom from = new BeanFrom();
        from.setTestString( "testString" );
        BeanTo to = new BeanTo();
        
        try {
            BeanUtils.copyProperties( to, from );
        } catch ( IllegalAccessException e ) {
            e.printStackTrace();
        } catch ( InvocationTargetException e ) {
            e.printStackTrace();
        }

        System.out.println( to.getTestString() );
    }
}

class BeanFrom {

    private String _testString;

    public String getTestString() {
        return _testString;
    }

    public void setTestString( String testString ) {
        this._testString = testString;
    }
}

class BeanTo {

    private String _testString;

    public String getTestString() {
        return _testString;
    }

    public void setTestString( String testString ) {
        this._testString = testString;
    }
}

输出的是:null!

但是把这三个类分别写在三个源文件中就没有关系,像这样
情况2(copy成功)、

BeanCopy.java
package com.hp9016.test.copyBean;

import java.lang.reflect.InvocationTargetException;

import org.apache.commons.beanutils.BeanUtils;

public class BeanCopy {

    public static void main( String[] args ) {
        ...代码同上
    }
}

BeanFrom.java
package com.hp9016.test.copyBean;

public class BeanFrom {
    ...代码同上
}


BeanTo.java
package com.hp9016.test.copyBean;

public class BeanTo {
    ...代码同上
}

输出:testString
正确。


我又试了下,
情况3(出现异常)
入口类和源类(即BeanCopy和BeanFrom类)写在一个源文件(即BeanCopy.java)中,则会抛出
[java.lang.reflect.InvocationTargetException: Cannot set testString]的异常。

情况4(copy失败)
入口类和目标类(即BeanCopy和BeanTo类)写在一个源文件(即BeanCopy.java)中,输出的结果仍然是null

用的是1.7的jar包,commons-beanutils-1.7.0-src.zip
http://archive.apache.org/dist/commons/beanutils/source/
看来面前只能先慢慢看源码了,有科学解释的别憋着啊
分享到:
评论
4 楼 hz86655032 2010-01-08  
顶一个楼主,有次面试,我也被问到相关的问题.
by the way,BeanUtils中有直接打印出某BEAN所有属性的方法吗?暂不考虑复杂对象属性.
3 楼 hp9016 2009-05-27  
jander 写道
用PropertyUtils试一下。
记得有一次遇到这个问题,用PropertyUtils解决了。
没深究什么原因,没精力啊。

哎,都下班了,整天做些无脑的活,好久没有研究这样的问题了。
看来我们遇到的情况不一样,不过没有精力倒是一样呀。
ok,我把题目改了,结贴了。
2 楼 hp9016 2009-05-27  
OK,知道了,分享一下。
根本原因是BeanUtils.copyProperties在复制bean的属性时对类与方法的可见性做了限制,即只能够copy拥有public修饰符的类和方法。

    研究源码我们可以发现,org.apache.commons.beanutils.PropertyUtilsBean这个类主要就是通过java的反射机制来获得bean属性,当然这个过程会检查bean可见性和命名合法性的问题,这以前本来是BeanUtils应该做的事情,参见http://commons.apache.org/beanutils/api/org/apache/commons/beanutils/PropertyUtilsBean.html。
    而上面出现错误的原因就出在这里。在方法getSimpleProperty中,上面的情况除了情况2之外,method都不能正常获得,是null(第1125行)。原来在通过MethodUtils获得method的可见性时出现了问题,如下(MethodUtils,getAccessibleMethod,415行):
        // If the declaring class is public, we are done
        Class clazz = method.getDeclaringClass();
        if (Modifier.isPublic(clazz.getModifiers())) {
            return (method);
        }

由于在一个源文件中只能有一个类是public的,而在上面的情况中,这个类只可能是入口类。所以没有修饰符的类BeanFrom与类BeanTo的getModifiers只能为0,因为它既不是public也不是final或者其他,参见[http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#75734]
Table 4.1
如此一来,就不能正常地返回method,导致属性的值不能被正常copy。

结论:使用BeanUtils.copyProperties作copybean的时候要注意源与目标的修饰符。为public。
1 楼 jander 2009-05-27  
用PropertyUtils试一下。
记得有一次遇到这个问题,用PropertyUtils解决了。
没深究什么原因,没精力啊。

相关推荐

    BeanMapper:比BeanUtils.copyProperties更快

    一个BeanUtils.copyProperties的小型快速替代。 起因 由于BeanUtils(Spring或Apache Commons)的copyProperties实现是利用反射实现的,它在大量调用时具有比较严重的性能问题。 BeanMapper通过javassist类库实现在...

    如何使用BeanUtils.copyProperties进行对象之间的属性赋值

    在这个`convertList2List`方法中,我们遍历输入列表(input),为每个元素创建一个新的目标对象实例(target),然后调用`BeanUtils.copyProperties`进行属性复制,最后将新对象添加到输出列表(output)。...

    BeanUtilsBean对象复制使用(类型可以自动转化)

    在Java开发中,Apache Commons BeanUtils库是一个非常实用的工具包,它提供了许多方便的方法来操作JavaBeans。本文将深入探讨`BeanUtilsBean`对象复制的功能,特别关注它如何实现类型自动转换。`BeanUtilsBean`是...

    commons-beanutils.jar.zip

    1. **属性拷贝**:BeanUtils.copyProperties()方法可以实现两个JavaBean对象之间的属性值拷贝,极大地减少了代码量。 2. **动态属性访问**:通过BeanUtils.getProperty()和BeanUtils.setProperty(),我们可以动态地...

    org.apache.commons.beanutils.jar

    Apache Commons BeanUtils是Apache软件基金会的一个开源项目,它提供了一组实用工具类,用于简化JavaBean对象的操作。这个库的核心是`org.apache.commons.beanutils`包,其中包含了大量的辅助方法,使得开发者可以...

    commons-beanutils-1.8.0.jar beanutils.jar beanutils.jar工具包

    commons-beanutils-1.8.0.jar beanutils.jar beanutils.jar工具包

    org.apache.commons.beanutils.BeanUtils实例

    此为BeanUtils的实例。其中apache的包有一个小的BUG已在其中说明。

    BeanUtils工具 .jar 包

    1. **属性复制**:BeanUtils.copyProperties()方法允许我们轻松地将一个Java Bean对象的属性值复制到另一个Bean对象。这对于在不同对象间传递数据或者创建对象的副本非常有用。例如,如果你有一个UserBean,你想创建...

    BeanUtils.jar

    1. **属性复制**:BeanUtils.copyProperties()是其最常用的功能之一,它能将一个对象的所有属性值复制到另一个对象中,大大减少了手动赋值的工作。 2. **类型转换**:BeanUtils.setProperty()和BeanUtils....

    commons-beanutils.jar

    然而,如果在服务器端没有正确引入"commons-beanutils.jar",那么在试图将Java对象转换为JSON时可能会出现问题。因为BeanUtils库包含了对象到JSON转换过程中必要的功能,比如属性的自动转换和映射。 "jar"文件是...

    commons.jar +commons-beanutils.jar

    标题中的"commons.jar +commons-beanutils.jar"指的是Apache Commons项目中的两个核心组件:commons.jar和commons-beanutils.jar。Apache Commons是Java编程语言中的一系列小型实用程序库,为开发人员提供了各种常见...

    commons-beanutils-1.9.4.jar.zip

    5. **拷贝属性**:`BeanUtils.copyProperties()`方法可以实现对象间的属性深度拷贝,这对于创建对象副本或者在不同对象间传递数据十分便利。 6. **避免空指针异常**:BeanUtils库在处理null值时会进行保护,避免因...

    Beanutils基本用法.doc

    Beanutils是一个强大的Java工具类库,主要用于简化JavaBean的属性操作。它提供了一系列的方法帮助开发者处理Bean的属性读取、设置以及转换等问题,尤其在处理复杂的Bean层级结构时表现突出。 #### 二、属性的动态...

    使用BeanUtils操作属性的一个小坑

    例如,我们可以使用`BeanUtils.copyProperties()`方法快速地将一个JavaBean的属性值复制到另一个JavaBean上。但请注意,这种方法默认会忽略源对象中不存在于目标对象的属性,而目标对象中未在源对象中找到的属性将...

    commons-beanutils所有版本(1.0-1.9.2).zip

    例如,在某些情况下,不恰当的使用`BeanUtils.copyProperties()`可能导致恶意代码执行。因此,使用时需谨慎,尤其是在处理用户输入时。 8. **替代品和扩展**: 随着Java生态的发展,其他库如Dozer、ModelMapper等...

    commons-beanutils.jar、commons-logging.jar两个包

    beanUtils 方便访问javaBean 附带支持框架 logging jar包,Apache提供的这个beanutils包极大方便了javabean的 操作。包含了最新的commons-beanutils-1.9.3.jar,以及其依赖的commons-logging-1.2.jar包

Global site tag (gtag.js) - Google Analytics