• 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-知乎

  • 相关阅读:
    Windows 系统共享文件扫描
    工业以太网EtherNet/IP协议安全分析整理
    说说搜索,你觉得自己的信息有多安全
    java网络编程
    攻击WordPress和其他程序
    ZenMap扫描笔记
    WireShark Wifi认证数据包分析(论文idea)
    linux 基础知识(三)
    unity 3D 学习笔记
    WPA-PSK无线网络密码破解原理
  • 原文地址:https://www.cnblogs.com/strongmore/p/15473447.html
Copyright © 2020-2023  润新知