轉載:http://blog.csdn.net/codershamo/article/details/52015206
objenesis簡介:
objenesis是一個小型Java類庫用來實例化一個特定class的對象。
使用場合:
Java已經支持使用Class.newInstance()動態實例化類的實例。但是類必須擁有一個合適的構造器。有很多場景下不能使用這種方式實例化類,比如:
-
構造器需要參數
-
構造器有side effects
-
構造器會拋異常
因此,在類庫中經常會有類必須擁有一個默認構造器的限制。Objenesis通過繞開對象實例構造器來克服這個限制。
典型使用
實例化一個對象而不調用構造器是一個特殊的任務,然而在一些特定的場合是有用的:
-
序列化,遠程調用和持久化 -對象需要實例化並存儲為到一個特殊的狀態,而沒有調用代碼。
-
代理,AOP庫和Mock對象 -類可以被子類繼承而子類不用擔心父類的構造器
-
容器框架 -對象可以以非標准的方式被動態實例化。
快速入門
Objenesis有兩個主要的接口:
ObjectInstantiator -實例化一個類的多個實例
interface ObjectInstantiator{ Object new Instance(); }
- 1
- 2
- 3
- 1
- 2
- 3
InstantiatorStrategy -對一個類的實例化進行特殊的策略處理(隨着類的不同而不同)
interface InstantiatorStrategy{ ObjectInstantiator newInstantiaorOf(Class type); }
- 1
- 2
- 3
- 1
- 2
- 3
注意:所有的Objenesis類都在org.objenesis包中
使用方法
根據jvm供應商,版本和類的安全管理和類型的不同, Objenesis實例化對象有許多不同的策略。
有兩種不同種類的實例化是必需的:
-
Stardard -沒有構造器會被調用
-
Serilizable compliant -與java標准序列化方式實例一個對象的行為一致。即第一個不可序列化的父類構造器將被調用。 但是,readResolve不會被調用並且不檢查對象是否是可序列化的。
最簡單的使用Objenesis的方法是使用ObjenesisStd(Standard) 和ObjenesisSerializer(Serializable compliant)。這兩種方式會自動選擇最好的策略。
Objenesis objenesis = new ObjenesisStd(); // or ObjenesisSerialializer
- 1
- 1
實現Objenesis接口后,就可以為一個特定的類型創建一個ObjectInstantiator
ObjectInstantiator thingInstantiator = objenesis.getInstantiatorOf(MyThingy.class);
- 1
- 1
最后,可以使用這個去新建實例
MyThingy thingy1 = (MyThingy)thingyInstantiator.newInstnace(); MyThingy thingy2 = (MyThingy)thingInstantiator.newInstance();
- 1
- 2
- 1
- 2
性能和多線程
為了提高性能,最好盡可能多的使用ObjectInstantiator 對象。 例如,如果要實例化一個類的多個對象,請使用相同的ObjectInstantiator。
InstantiatorStrategy和ObjectInstantiator都可以在多線程中共享並發使用,它們是線程安全的。
代碼示例:
Objenesis objenesis = new ObjenesisStd(); // or ObjenesisSerializer MyThingy thingy1 = (MyThingy) objenesis.newInstance(MyThingy.class); // or (a little bit more efficient if you need to create many objects) Objenesis objenesis = new ObjenesisStd(); // or ObjenesisSerializer ObjectInstantiator thingyInstantiator = objenesis.getInstantiatorOf(MyThingy.class); MyThingy thingy2 = (MyThingy)thingyInstantiator.newInstance(); MyThingy thingy3 = (MyThingy)thingyInstantiator.newInstance(); MyThingy thingy4 = (MyThingy)thingyInstantiator.newInstance();