年过三十仍在路上

平凡而不平庸,低调而不颓废 两耳不闻人声,只有硬盘在歌唱

常用链接

统计

印刷报价

印刷设备

友情链接

最新评论

实现不调用构造方法创建对象

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

能不能有办法绕过构造方法来实例化一个对象呢?

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

从运行平台上得到几个关键的参数,如下:

/** 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");

然后根据得到的参数进行判断:

根据得到平台提供的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获取对象。

项目主页:http://objenesis.googlecode.com/svn/docs/index.html

posted on 2009-08-20 08:53 和风赛跑 阅读(1769) 评论(5)  编辑  收藏

评论

# re: 实现不调用构造方法创建对象 2009-08-20 09:11 BoBo小说网

值得参考下  回复  更多评论   

# re: 实现不调用构造方法创建对象 2009-08-20 09:12 BoBo小说网

实际应用中还是很多的  回复  更多评论   

# re: 实现不调用构造方法创建对象 2009-08-20 09:53 隔叶黄莺

对的,在 XStream 转换 XML 或 JSON 到 JavaBean 时用得就是 sun.reflect.ReflectionFactory,所以不依赖于 JavaBean 的构造函数。  回复  更多评论   

# re: 实现不调用构造方法创建对象 2009-08-21 17:46 个性艺术签名

实际应用中还是很多的  回复  更多评论   

# re: 实现不调用构造方法创建对象 2009-08-25 08:50 找个美女做老婆

Java乐园学习网站: http://www.javaly.cn

有大量的学习文章和视频教程,以及一些项目源码

Java乐园学习群: 81107233  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: