如果一個類沒有參數(shù)為空的構(gòu)造方法時候,那么你直接調(diào)用newInstance方法試圖得到一個實例對象的時候是會拋出異常的。
能不能有辦法繞過構(gòu)造方法來實例化一個對象呢?
Objenesis 為其提供了在四個不同的jvm上的解決方案。
首先我們看看四個不同的jvm平臺:
- Sun Hotspot VM, versions 1.3, 1.4, 1.5 and 1.6
- GCJ version 3.4.4 (tested on Windows/Cygwin)
- BEA JRockit versions 7.0 (1.3.1), 1.4.2 and 1.5
- Aonix PERC (no serialization support), tested on version 5.0.0667
從運行平臺上得到幾個關(guān)鍵的參數(shù),如下:
/**
JVM version */
protected static final String VM_VERSION = System.getProperty("java.runtime.version");
/**
JVM version */
protected static final String VM_INFO = System.getProperty("java.vm.info");
/**
Vendor version */
protected static final String VENDOR_VERSION = System.getProperty("java.vm.version");
/**
Vendor name */
protected static final String VENDOR = System.getProperty("java.vm.vendor");
/**
JVM name */
protected static final String JVM_NAME = System.getProperty("java.vm.name");
然后根據(jù)得到的參數(shù)進行判斷:
根據(jù)得到平臺提供的jvm版本和供應(yīng)商來選擇不同的實例化策略。
說實話,這幾個平臺里面我還是對sun公司提供的相對熟悉一些,所以除了sun公司提供的jvm對于的實例策略我在這里就不介紹了,
大家有興趣的話可以去項目主頁下載下來細細研究。
現(xiàn)在我們僅僅關(guān)注sun公司的,并且版本大于1.3的。
版本為1.3的jvm具體實例化策略這里不做討論了,有興趣的可以去看objenesis的實現(xiàn)。
代碼如下:
import
sun.reflect.ReflectionFactory;
public class SunReflectionFactoryInstantiator implements ObjectInstantiator {
private final Constructor mungedConstructor;
public SunReflectionFactoryInstantiator(Class type) {
ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
Constructor javaLangObjectConstructor;
try {
javaLangObjectConstructor = Object.class.getConstructor((Class[]) null);
}
catch(NoSuchMethodException e) {
throw new Error("Cannot find constructor for java.lang.Object!");
}
mungedConstructor = reflectionFactory.newConstructorForSerialization(type,
javaLangObjectConstructor);
mungedConstructor.setAccessible(true);
}
public Object newInstance() {
try {
return mungedConstructor.newInstance((Object[]) null);
}
catch(Exception e) {
throw new ObjenesisException(e);
}
}
}
通過
sun.reflect.ReflectionFactory這個類來實例化一個class那么就繞過了其類的構(gòu)造方法,我們可以暫且稱之為繞道方式實例一個對象。
希望上面的代碼能給大家起到一定的幫助,另外
easymock的最新版本已經(jīng)使用了Objenesis來實例化一個Class獲取對象。
項目主頁:http://objenesis.googlecode.com/svn/docs/index.html