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

联合创作 · 2023-09-28 21:14

如果一个类没有参数为空的构造方法时候,那么你直接调用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

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

  1. /** JVM version */

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


  3. /** JVM version */

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


  5. /** Vendor version */

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


  7. /** Vendor name */

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


  9. /** JVM name */

  10. protected static final String JVM_NAME = System.getProperty("java.vm.name");  

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

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

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

代码如下:

  1. import sun.reflect.ReflectionFactory;    

  2. public class SunReflectionFactoryInstantiator implements ObjectInstantiator {   


  3. private final Constructor mungedConstructor;   


  4. public SunReflectionFactoryInstantiator(Class type) {    


  5. ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();    

  6. Constructor javaLangObjectConstructor;   


  7. try {    

  8. javaLangObjectConstructor = Object.class.getConstructor((Class[]) null);   

  9. }   

  10. catch(NoSuchMethodException e) {    

  11. throw new Error("Cannot find constructor for java.lang.Object!");    

  12. }   

  13. mungedConstructor = reflectionFactory.newConstructorForSerialization(type,    

  14. javaLangObjectConstructor);   

  15. mungedConstructor.setAccessible(true);   

  16. }   


  17. public Object newInstance() {    

  18. try {    

  19. return mungedConstructor.newInstance((Object[]) null);   

  20. }   

  21. catch(Exception e) {    

  22. throw new ObjenesisException(e);   

  23. }   

  24. }   

  25. }   


通过sun.reflect.ReflectionFactory这 个类来实例化一个class那么就绕过了其类的构造方法,我们可以暂且称之为绕道方式实例一个对象。
希望上面的代码能给大家起到一定的帮助,另外easymock的 最新版本已经使用了Objenesis来实例化一个Class获取对象。

介绍来自 blogjava— @和风赛跑

浏览 6
点赞
评论
收藏
分享

手机扫一扫分享

编辑 分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

编辑 分享
举报