利用EZMorph複製Bean
引子
眾所周知,在java中對象之間的賦值是地址參考關聯性,如:
- A a = new A();
- A b = a;
則修改b的屬性,a的屬性也會跟著修改。
在很多場合下,我們希望複製出一個新的對象出來,新對象的修改不會影響原有對象,這時我們一般常用的有如下兩種方式:
- 使對象實現Cloneable介面,這個只適用於我們自己的java對象
- 使用jakatar commons的BeanUtils實現bean copy
昨晚看到一個新的組件:EZMorph,可以實現同樣的功能,這裡簡單介紹一下。
EZMorph據說起源於json,後來獨立出來了,有興趣的可以到官網(http://ezmorph.sourceforge.net/)上瀏覽一下。
EZMorph的主要原理
若要將A的屬性賦給B,則經過如下步驟:
- new一個B的執行個體
- 遍曆A的屬性
- 若A有某個屬性P1,B也有一個屬性P1,則將A的P1的屬性值賦給B的P1
程式碼範例
1. 先看幾個簡單類型的樣本
int i = new IntMorpher().morph("123");<br />Assert.assertEquals(123, i); // true!<br />String str = (String) StringMorpher.getInstance().morph(new Integer(123));<br />Assert.assertEquals("123", str); // true!<br />Boolean[] bools = (Boolean[]) new ObjectArrayMorpher(new BooleanObjectMorpher()).morph(new String[] { "true","false" });<br />Assert.assertEquals(Boolean.TRUE, bools[0]); // true!<br />Assert.assertEquals(Boolean.FALSE, bools[1]); // true!<br />MorpherRegistry morperRegistry = new MorpherRegistry();<br />MorphUtils.registerStandardMorphers(morperRegistry);<br />Integer x = (Integer) morperRegistry.morph(Integer.class, "2");<br />Assert.assertEquals(new Integer(2), x); // true!
2. 再看一下java.util.Calendar對象
MorpherRegistry morperRegistry = new MorpherRegistry();<br />MorphUtils.registerStandardMorphers(morperRegistry);<br />Calendar dynaBean = Calendar.getInstance(); // initialized elsewhere<br />System.out.println(dynaBean.getTime());<br />morperRegistry.registerMorpher(new BeanMorpher(GregorianCalendar.class,morperRegistry));<br />Calendar myBean = (Calendar) morperRegistry.morph(GregorianCalendar.class, dynaBean);
注意: morperRegistry.registerMorpher( new BeanMorpher( GregorianCalendar.class, morperRegistry ) );
這裡必須填寫GregorianCalendar類型,如果用Calendar.class就會報出異常,因為EZMorph只能處理public類型的構造方法,而Calendar的構造方法是protected的。這種情況下,最好還是使用Calendar的clone功能。
3. 再看一下,不同對象之間的賦值
Student類
public class Student {<br />private int age;<br />private String name;<br />public int getAge() {<br />return age;<br />}<br />public void setAge(int age) {<br />this.age = age;<br />}<br />public String getName() {<br />return name;<br />}<br />public void setName(String name) {<br />this.name = name;<br />}</p><p>public void hi(int age,String name){<br />System.out.println("我是"+name+",今年"+age+"歲");<br />}<br />}
Tearcher
public class Teacher {<br />private String id;<br />private String name;<br />public String getId() {<br />return id;<br />}<br />public void setId(String id) {<br />this.id = id;<br />}<br />public String getName() {<br />return name;<br />}<br />public void setName(String name) {<br />this.name = name;<br />}<br />}
將Student對象的name屬性賦給Teacher對象的name中
MorpherRegistry morperRegistry = new MorpherRegistry();<br />Student student = new Student();<br />student.setName("chb");<br />morperRegistry.registerMorpher(new BeanMorpher(Teacher.class,morperRegistry));<br />Teacher teacher = (Teacher) morperRegistry.morph(Teacher.class, student);<br />System.out.println(teacher.getId());<br />System.out.println(teacher.getName());
輸出結果為:
null
chb
可以看出Student和Teacher都有name屬性,因此將屬性值拷貝過來了,而Student沒有id屬性,因此Teacher對象的id屬性值為空白。
總結:對於Bean的copy功能還是不錯的,特別是在多線程情況下的應用