關於BeanUtils中copyProperties方法的研究體會!

Struts中經常看到BeanUtils.copyProperties這個方法滿天飛,特別是在提取表單中的值的時候,但是這個方法具體怎麼實現屬性的複製卻一直不是很明白,特別是在複製屬性的時候,比方說把b複製到aBeanUtils.copyProperties(a,b),是不是把b的所有屬性都複製過去了呢?如果是同一個屬性,b中的值是不是會覆蓋掉a中的值?這些應該都可以從BeanUtils的源碼中得到答案,奈何找了半天沒找到源碼,在網上也沒有找到別人的答覆,於是本着實踐是檢驗真理的唯一標準,決定親自測試一把,^_^

首先我們構建兩個類PeoplePerson,它們的實例呆會會用來相互複製。

People.java

package com.mangocity.test;

 

/**

 * @author CMTobby

 */

public class People {

 

    public People() {

       // TODO Auto-generated constructor stub

    }

   

    private String name;//姓名

    private int age;//年齡

    private String email;

   

    public String getEmail() {

       return email;

    }

    public void setEmail(String email) {

       this.email = email;

    }

    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;

    }

}

 

 

Person.java

package com.mangocity.test;

 

/**

 * @author CMTobby

 */

public class Person {

    private String name;

    private int age;

    private String address;

   

    public String getAddress() {

       return address;

    }

    public void setAddress(String address) {

       this.address = address;

    }

    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;

    }

}

 

接着構建我們的測試類

import org.apache.commons.beanutils.*;

public class TestBeanUtils {

 

    /**

     * @param args

     */

    public static void main(String[] args) {

       // TODO Auto-generated method stub

       People tobby=new People();

       Person cindy=new Person();

       tobby.setAge(23);

       tobby.setName("CMTobby");

       tobby.setEmail("[email protected]");

 

       cindy.setName("Cindyelf");

       cindy.setAge(24);

        try {

             BeanUtils.copyProperties(cindy, tobby);

           System.out.println(cindy.getName()+":"+cindy.getAge());

       } catch (IllegalAccessException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       } catch (InvocationTargetException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       }

    }

}

 

運行該程序輸出是:CMTobby:23。這說明經過BeanUtils.copyProperties之後cindynameage屬性的值已經被tobby中的同名屬性給“覆蓋”了,至於tobby中有而cindy中沒有的email屬性有沒有複製到cindy中就不得而知了,據我的猜測應該是沒有的,因爲在cindy中沒有地方放這個屬性啊,而且就算複製過去了,我們如何得到這個值呢?難道用cindy.getEmail()嗎,可是cindy根本沒有這個方法啊?當然這只是我的猜測,不知哪位達人有準確的答案,歡迎指正,^_^

那麼這個複製過程是如何的呢?是直接屬性對屬性的值拷貝嗎,例如cindy.name=tobby.name?還是老辦法,將測試進行到底。

1.我將Person中的name屬性改名爲name11age屬性改爲age11getset方法都做相應的修改,此時運行程序,輸出結果爲:CMTobby:23,和前面的一樣,由此可以排除值拷貝這個假設了,因爲此時cindy中沒有了name屬性而是name11屬性。

2.我將Person中的setNamesetAge方法分別改爲setName11setAge11.OK,再次運行我們的程序,這時的輸出是:Cindyelf:24,我們發現cindyname屬性和age屬性的值都沒有被覆蓋掉,也就是說tobby中的值都沒有拷貝過來,爲什麼呢?

3.將我們程序恢復到剛開始的樣子,即上面所貼的代碼那樣,然後將Person中的setAge方法註釋掉,並註釋掉TestBeanUtils中的cindy.setAge(24)這行代碼。運行程序,輸出結果是:CMTobby:0tobbyage屬性的值沒有拷貝過來,爲什麼呢?

基於上述兩個測試,我猜測BeanUtils.copyProperties的行爲過程是這樣的:首先通過java的反射得到tobby中的所有域,然後根據域的名字調用cindy中相應的set方法。舉個例子,BeanUtils發現tobby中有個name屬性,那麼它會嘗試執行cindy.setName()這個方法。這就很容易解釋測試2和測試3的結果了:因爲cindy中沒有了setName或者setAge(被改成了setName11setAge11或者被註釋掉了),所有cindyname屬性不會變,仍然是以前的值。而在測試1中,因爲cindy對象有setName方法,所以name11屬性的值會被覆蓋掉。

做完上述測試之後,我閒着無聊又做了如下兩個測試:

4.Person中的setNamesetAge改爲setnamesetage,程序輸出結果是:CMTobby:23cindy中的name屬性和age屬性的值都發生了變化;

5.Person中的setNamesetAge改爲setNAmesetAGe,程序輸出結果是:Cindyelf:24tobby中的屬性的值都沒有拷貝過來。

基於這兩個測試,我想過程會不會是這樣的:如果BeanUtils發現tobby中有個name屬性,那麼它就會嘗試執行cindy.setName()或者cindy.setname()。當然這些都只是我的推論,僅供參考,所有的答案都會在BeanUtils的源碼中找到,^_^,還望哪位達人不吝告知。

發佈了13 篇原創文章 · 獲贊 2 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章