• 不使用构造方法创建Java对象: objenesis的基本使用方法


    转载:http://blog.csdn.net/codershamo/article/details/52015206

    objenesis简介:

    objenesis是一个小型Java类库用来实例化一个特定class的对象。

    使用场合:

    Java已经支持使用Class.newInstance()动态实例化类的实例。但是类必须拥有一个合适的构造器。有很多场景下不能使用这种方式实例化类,比如:

    • 构造器需要参数

    • 构造器有side effects

    • 构造器会抛异常

    因此,在类库中经常会有类必须拥有一个默认构造器的限制。Objenesis通过绕开对象实例构造器来克服这个限制。

    典型使用

    实例化一个对象而不调用构造器是一个特殊的任务,然而在一些特定的场合是有用的:

    • 序列化,远程调用和持久化 -对象需要实例化并存储为到一个特殊的状态,而没有调用代码。

    • 代理,AOP库和Mock对象 -类可以被子类继承而子类不用担心父类的构造器

    • 容器框架 -对象可以以非标准的方式被动态实例化。

    快速入门

    Objenesis有两个主要的接口:

    ObjectInstantiator -实例化一个类的多个实例

    interface ObjectInstantiator{
        Object new Instance();
    }
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

    InstantiatorStrategy -对一个类的实例化进行特殊的策略处理(随着类的不同而不同)

    interface InstantiatorStrategy{
        ObjectInstantiator newInstantiaorOf(Class type);    
    }
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

    注意:所有的Objenesis类都在org.objenesis包中

    使用方法

    根据jvm供应商,版本和类的安全管理和类型的不同, Objenesis实例化对象有许多不同的策略。 
    有两种不同种类的实例化是必需的:

    • Stardard -没有构造器会被调用

    • Serilizable compliant -与java标准序列化方式实例一个对象的行为一致。即第一个不可序列化的父类构造器将被调用。 但是,readResolve不会被调用并且不检查对象是否是可序列化的。

    最简单的使用Objenesis的方法是使用ObjenesisStd(Standard) 和ObjenesisSerializer(Serializable compliant)。这两种方式会自动选择最好的策略。

    Objenesis objenesis = new ObjenesisStd(); // or ObjenesisSerialializer
    • 1
    • 1

    实现Objenesis接口后,就可以为一个特定的类型创建一个ObjectInstantiator

    ObjectInstantiator thingInstantiator = objenesis.getInstantiatorOf(MyThingy.class);
    • 1
    • 1

    最后,可以使用这个去新建实例

    MyThingy thingy1 = (MyThingy)thingyInstantiator.newInstnace();
    MyThingy thingy2 = (MyThingy)thingInstantiator.newInstance();
    • 1
    • 2
    • 1
    • 2

    性能和多线程

    为了提高性能,最好尽可能多的使用ObjectInstantiator 对象。 例如,如果要实例化一个类的多个对象,请使用相同的ObjectInstantiator。 
    InstantiatorStrategy和ObjectInstantiator都可以在多线程中共享并发使用,它们是线程安全的。

    代码示例:

    Objenesis objenesis = new ObjenesisStd(); // or ObjenesisSerializer
    MyThingy thingy1 = (MyThingy) objenesis.newInstance(MyThingy.class);
    
    // or (a little bit more efficient if you need to create many objects)
    
    Objenesis objenesis = new ObjenesisStd(); // or ObjenesisSerializer
    ObjectInstantiator thingyInstantiator = objenesis.getInstantiatorOf(MyThingy.class);
    
    MyThingy thingy2 = (MyThingy)thingyInstantiator.newInstance();
    MyThingy thingy3 = (MyThingy)thingyInstantiator.newInstance();
    MyThingy thingy4 = (MyThingy)thingyInstantiator.newInstance();
  • 相关阅读:
    【C语言入门教程】5.6 函数库和文件
    【C语言入门教程】5.5 实现问题(效率)
    【C语言入门教程】5.4 递归
    【C语言入门教程】5.3 函数的调用 与 参数
    【C语言入门教程】5.2 函数的作用域规则(auto, static)
    bootstrap之双日历时间段选择控件示例—daterangepicker(中文汉化版)
    PHP导出数据到CSV文件函数 csv_export()
    MySQL 5.6 Warning: Using a password on the command line interface can be insecure
    【定时任务|开机启动】Windows Server 2008/2012 计划任务配置(任务计划程序)每分钟执行BAT
    【风雪之隅】写在PHP7发布之际一些话 2015-12-02
  • 原文地址:https://www.cnblogs.com/fanguangdexiaoyuer/p/6429459.html
Copyright © 2020-2023  润新知