java中Objenesis庫簡單使用


前言

Objenesis是一個小的java庫,主要用來實例化類對象,java本身僅支持通過構造器實例化,實例化時必須使用合適的構造器,但有些情況下不能使用這種方式實例化:

  • 構造器需要參數
  • 構造器有副作用
  • 構造器會拋異常

一些常見的類庫都要求類包含一個默認的無參構造器,而Objenesis可以繞過構造器來實例化對象。

簡單使用

定義一個用來實例化的類,不包含默認構造器

public class User {

  private String name;

  public User(String name) {
    System.out.println("User.Constructor");
  }

  @Override
  public String toString() {
    return "User.toString()";
  }
}

使用Objenesis實例化對象

import org.objenesis.Objenesis;
import org.objenesis.ObjenesisStd;
import org.objenesis.instantiator.ObjectInstantiator;

public class TestObjenesis {

  public static void main(String[] args) {
    //創建Objenesis,內部包含一個實例化策略對象StdInstantiatorStrategy
    Objenesis objenesis = new ObjenesisStd();
    //獲取對象實例化器
    ObjectInstantiator objectInstantiator = objenesis.getInstantiatorOf(User.class);
    //實例化對象
    System.out.println(objectInstantiator.newInstance());
  }

}

輸出結果為

User.toString()

根據輸出結果可以得知確實繞過了構造器。

實現原理

默認使用的實例化策略對象類型為StdInstantiatorStrategy,會根據JVM供應商的不同,JVM版本的不同來選擇不同的實例化器。
如我們使用的HotSpot虛擬機,就會使用SunReflectionFactoryInstantiator實例化器,底層使用ReflectionFactory類來實例化對象,
關於ReflectionFactory的使用,可以查看 java魔法類之ReflectionFactory介紹 這篇博客。
如果上述條件都不滿足就會使用UnsafeFactoryInstantiator實例化器,內部使用Unsafe類的allocateInstance()方法實例化對象,
關於Unsafe,可以查看 java魔法類之Unsafe介紹 這篇博客。

使用場景

Spring中集成了Objenesis庫,在使用Cglib創建動態代理對象時就使用到了Objenesis。

Spring中定義的SpringObjenesis和Objenesis中的標准實現ObjenesisStd相比,在使用緩存時,使用Class對象代替Class名稱作為緩存的key。

參考

objenesis官網
objenesis-知乎


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM