不使用构造方法创建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();
相关文章
- 对Object使用toString方法出现空指针异常java.lang.NullPointerException
- java对象组声明_如何在Java中声明对象数组?
- java工具类-Java对象转换成Map
- java数组的声明_Java数组定义常用方法[通俗易懂]
- java反转数组_Java实现数组反转翻转的方法实例
- java中random方法取值范围_Java Random.nextInt()方法,随机产生某个范围内的整数
- java 读取字符串文件_Java读取文件为字符串
- 【说站】java反射获取对象的方法
- 【说站】java成员方法是什么?
- java验证手机号正则表达式_Java使用正则表达式验证手机号和电话号码的方法「建议收藏」
- java notifyall_Java Thread notifyAll()方法[通俗易懂]
- Effective-java-读书笔记之对于所有对象都通用的方法
- 微信开发SDK java版,支持maven;微信Java开发工具包,支持包括微信支付、开放平台、公众号、企业微信/企业号、小程序等微信功能模块的后端开发。
- java 对象拷贝方法beanutils_java copy方法
- JAVA代码审计之java反序列化
- java解释器虚拟机-【Java解释器和编译器】解释器和编译器的深入理解
- 请不要再说 Java 中 final 方法比非 final 性能更好了详解编程语言
- [javaEE] EL表达式调用java方法详解编程语言
- Java Math.sqrt()方法详解编程语言
- 解决Java程序连接MySQL数据库的方法(java链接mysql数据库)
- Java Map.values()方法:获取Map集合中的所有键值对象
- Java Set.remove()方法:移除Set集合中的指定对象
- Java List.add()方法:向集合列表中添加对象
- 时间处理 Java 中Redis过期时间的方法(redisjava过期)
- Java如何帮助掌握Oracle(java了解oracle)
- java从list中取出对象并获得其属性值的方法
- java生成申请单序列号的实现方法
- Java动态调用类中方法代码
- Java利用反射自动封装成实体对象的方法
- JS自定义对象实现Java中Map对象功能的方法