BeanUtils.cloneBean()

本以为这个方法可以方便的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方法的类准备的



作者: lich0079 
声明: 本文系JavaEye网站发布的原创文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!

已有 2 人发表回复,猛击->>这里<<-参与讨论


JavaEye推荐



posted @ 2009-12-18 15:36  Fervour  阅读(7464)  评论(1编辑  收藏  举报