如果一个类没有参数为空的构造方法时候,那么你直接调用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获取对象。
分享到:
相关推荐
Objenesis 提供了一种规避这种问题的方法,它能绕过Java的构造器,直接创建对象,即使这个类没有任何公共构造器。 EasyMock 是一个模拟框架,它允许程序员在测试时创建模拟对象,这些模拟对象可以按照预设的行为...
其次,Objenesis是一个快速且轻量级的库,用于在Java中创建对象,特别是在没有无参构造函数或构造函数需要参数的情况下。Objenesis主要解决了Java中new关键字的局限性,它能跳过构造函数的执行,快速实例化对象。在...
Objenesis则为Spring提供了快速创建对象的能力,尤其在测试环境中,避免了对复杂初始化逻辑的依赖。 在实际项目中,当开发者引入Spring框架时,这些库通常会被自动管理,无需直接操作。然而,理解它们的工作原理有...
ObjenesisHelper是Objenesis库中的一个关键组件,它提供了创建对象实例的能力。当你看到上述错误,很可能是你的项目依赖中缺少Objenesis库,或者版本不匹配。 在给定的压缩包"objenesis-1.2"中,包含了Objenesis的...
Objenesis通过利用Java虚拟机(JVM)的内部机制,能够在没有调用构造函数的情况下创建对象,这在处理无参构造函数或私有构造函数的类时特别有用。 在Objenesis 3.2中,我们有两个主要的JAR文件: 1. `objenesis-...
Objenesis就是为此目的而设计的,它能够绕过Java的默认构造函数,快速地创建对象。Objenesis-repack版本同样是为了适应Spring框架,确保与其他库的兼容性。 3. **动态代理**: 在Spring中,动态代理是实现AOP...
Objenesis使用Java的反射API,但它通过一些内部优化和技巧,能够在不调用任何构造函数的情况下创建对象,这对于某些特殊场景(例如CGLIB的字节码操作)非常有用。版本2.5.1也是经过验证和优化的版本,确保了兼容性和...
在Spring中,Objenesis主要用于处理一些特殊情况,比如在CGLIB代理中,当目标类没有无参构造函数时,Objenesis可以帮助创建对象实例。 Objenesis的主要特点: 1. 快速:Objenesis设计为快速且高效,避免了传统构造...
在某些情况下,如测试或AOP场景,可能需要在不调用构造函数的情况下创建对象。Objenesis可以做到这一点,它能够绕过Java的默认构造器,即使在类没有无参构造器的情况下也能创建实例。"spring-objenesis-repack-2.6....
在某些情况下,如Spring框架的某些内部机制,比如InstantiationAwareBeanPostProcessors,可能需要在不调用任何构造函数的情况下创建对象,这时Objenesis就能提供帮助。Objenesis可以绕过Java的常规构造过程,从而...
Objenesis是一个轻量级库,主要用来在Java中创建实例,尤其是对于无参构造函数的类,它可以在不触发初始化的情况下创建对象。这在某些测试场景或者特殊情况下非常有用,比如Spring的Proxy代理模式,它可能需要在对象...
当目标对象不支持接口或者为了性能考虑不需要创建接口时,Spring会使用CGLIB来动态生成一个子类,然后通过这个子类来拦截并增强方法的执行。CGLIB生成的子类会在运行时动态添加一些额外的功能,如记录日志、性能监控...
Objenesis是一个Java库,用于在没有调用构造函数的情况下实例化类,这在某些场景下非常有用,比如测试或者需要快速创建对象的场合。在Spring框架中,Objenesis用于在无参构造函数不可用或不可访问时,帮助初始化对象...
在某些场景下,如Spring的测试或代理创建中,可能需要在不调用构造函数的情况下创建对象。Objenesis通过利用Java的反射和字节码操作来实现这一点。在Spring中,Objenesis常与CGLIB结合使用,尤其是在CGLIB不能通过...
Objenesis是一个专门用于在创建对象时绕过构造函数的库。 在任何JVM上都有。 您可以在找到网站和用户文档。 开发者信息 项目状态 环境设定 我正在使用: Maven 3.6.3 IntelliJ Ultimate 2021.1(感谢JetBrains的...
在Spring框架中,CGLIB被用于AOP代理,特别是当目标对象不能实现接口时,Spring会使用CGLIB来创建代理对象,实现对方法的增强。CGLIB通过字节码操作技术,可以在运行时动态生成一个新的类,这个新类继承自目标类,并...
Objenesis是一个轻量级库,主要用于在Java中创建对象,尤其是在类没有无参构造函数或者构造函数有访问限制的情况下。在Spring框架中,Objenesis主要在实例化代理对象时发挥作用,特别是在CGLIB无法正常工作的时候,...
当目标对象不支持接口(即为final类或者没有接口的类)时,Spring会使用CGlib来创建代理对象。通过这种方式,Spring能够注入切面逻辑,比如日志记录、事务管理等,即使在不修改原有代码的情况下也能实现扩展功能。 ...
Objenesis是一个轻量级库,它的主要目的是在Java中创建对象,即使这些对象的构造函数有特定的要求,如私有构造函数或需要参数。在Spring框架中,Objenesis主要用于测试场景,特别是与CGLIB结合使用时,它能帮助快速...