zoukankan      html  css  js  c++  java
  • 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-知乎

  • 相关阅读:
    给图片加自定义字体水印
    [ZT]互联网网站应该如何存储密码?
    【Best Practice】在JAVA里面反序列化.NET的对象。
    关于权限验证的两篇好文
    U盘安装Ubuntu遇到的奇怪问题
    const 用法
    程序员进级攻略
    搞混的指针数组与数组指针
    C/C++内存分配
    多个常见代码设计缺陷(转载)
  • 原文地址:https://www.cnblogs.com/strongmore/p/15473447.html
Copyright © 2011-2022 走看看