Objenesis 快速入门教程

是一个轻量级的Java库,作用是绕过构造器创建一个实例。

Objenesis is a small Java library that serves one purpose: To instantiate a new object of a particular class.

Java已经支持通过Class.newInstance()动态实例化Java类,但是这需要Java类有个适当的构造器。很多时候一个Java类无法通过这种途径创建,例如:

    构造器需要参数 构造器有副作用 构造器会抛出异常

Objenesis可以绕过上述限制。它一般用于:

    序列化、远程处理和持久化:无需调用代码即可将Java类实例化并存储特定状态。 代理、AOP库和Mock对象:可以创建特定Java类的子类而无需考虑super()构造器。 容器框架:可以用非标准方式动态实例化Java类。例如Spring引入Objenesis后,Bean不再必须提供无参构造器了。

接口介绍

Objenesis中有两个重要的接口:

ObjectInstantiator - Instantiates multiple instances of a single class.

interface ObjectInstantiator {
          
   
  Object newInstance();
}

InstantiatorStrategy - A particular strategy for how to instantiate a class (as this differs for different types of classes).

interface InstantiatorStrategy {
  ObjectInstantiator newInstantiatorOf(Class type);
}

Note: All Objenesis classes are in the org.objenesis package.

具体示例

There are many different strategies that Objenesis uses for instantiating objects based on the JVM vendor, JVM version, SecurityManager and type of class being instantiated. We have defined that two different kinds of instantiation are required: Stardard - No constructor will be called Serializable compliant - Acts like an object instantiated by java standard serialization. It means that the constructor of the first non-serializable parent class will be called. However, readResolve is not called and we never check if the object is serializable. The simplest way to use Objenesis is by using ObjenesisStd (Standard) and ObjenesisSerializer (Serializable compliant). By default, automatically determines the best strategy - so you don’t have to.

1.构造ObjenesisStd

Objenesis objenesis = new ObjenesisStd(); // or ObjenesisSerializer

2.有了Objenesis 就可以通过getInstantiatorOf方法创建ObjectInstantiator对象了

ObjectInstantiator thingyInstantiator = objenesis.getInstantiatorOf(MyThingy.class);

3.实例化某个具体的类

MyThingy thingy1 = (MyThingy)thingyInstantiator.newInstance();
MyThingy thingy2 = (MyThingy)thingyInstantiator.newInstance();
MyThingy thingy3 = (MyThingy)thingyInstantiator.newInstance();

性能

InstantiatorStrategy 和ObjectInstantiator 类都是线程安全的,可以在多线程环境下共享使用。

To improve performance, it is best to reuse the ObjectInstantiator objects as much as possible. For example, if you are instantiating multiple instances of a specific class, do it from the same ObjectInstantiator. Both InstantiatorStrategy and ObjectInstantiator can be shared between multiple threads and used concurrently. They are thread safe.

参考资料

Twenty Second Tutorial:

经验分享 程序员 微信小程序 职场和发展