不使用构造方法创建对象 Objenesis

如果一个类没有参数为空的构造方法时候,那么你直接调用newInstance方法试图得到一个实例对象的时候是会抛出异常的。能不能有 办法绕过构造方法来实例化一个对象呢?

Objenesis 为其提供了在四个不同的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
从运行平台上得到几个关键的参数,如下:


protected static final String VM_VERSION = System.getProperty("java.runtime.version");


protected static final String VM_INFO = System.getProperty("java.vm.info");


protected static final String VENDOR_VERSION = System.getProperty("java.vm.version");


protected static final String VENDOR = System.getProperty("java.vm.vendor");


protected static final String JVM_NAME = System.getProperty("java.vm.name");
然后根据得到的参数进行判断:

根据得到平台提供的jvm版本和供应商来选择不同的实例化策略。
说实话,这几个平台里面我还 是对sun公司提供的相对熟悉一些,所以除了sun公司提供的jvm对于的实例策略我在这里就不介绍了,
大家有兴趣的话可以去项目主页下载下来细 细研究。

现在我们仅仅关注sun公司的,并且版本大于1.3的。
版本为1.3的jvm具体实例化策略这里不做讨论了,有兴趣的可 以去看objenesis的实现。

代码如下:

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那么就绕过了其类的构造方法,我们可以暂且称之为绕道方式实例一个对象。
希望上面的代码能给大家起到一定的帮助,另外easymock的 最新版本已经使用了Objenesis来实例化一个Class获取对象。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值