不使用构造方法创建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();
不使用构造方法创建Java对象: objenesis的基本使用方法的更多相关文章
- Java中JNI的使用详解第四篇:C/C++中创建Java对象和String字符串对象及对字符串的操作方法
首先来看一下C/C++中怎么创建Java对象:在JNIEnv中有两种方法是用来创建Java对象的: 第一种方法: jobject NewObject(jclass clazz , jmethodI ...
- [课本10.1.4]JDBC数据库连接池- C3P0数据源--通过构造方法创建数据源对象--通过配置文件创建数据源对象[推荐]
JDBC- C3P0数据源 /*重点提醒*/ 连接数据库的较低的jar包版本会与较高版本的mysql版本有冲突; 通过把mysql 8.0的版本降到5.5, jar包仍使用较高的 mysql-conn ...
- 除了使用new关键字,还有什么方法可以创建Java对象呢?
今天来盘点一下除了使用 "new" 关键字创建对象,还有什么方法可以创建Java对象呢? 因为是创建对象,所以这里ioc容器不在范围内 我们先看一下常用的new关键字创建 Clas ...
- IntelliJ IDEA平台下JNI编程(五)—本地C代码创建Java对象及引用
本文学习如何在C代码中创建Java对象和对象数组,前面我们学习了C代码中访问Java对象的属性和方法,其实在创建对象时本质上也就是调用构造函数,因此本文知识学习起来也很轻松.有了前面学习数组创建的方法 ...
- JNI_Z_08_创建Java对象
1.步骤 : (1).获取 jclass (2).获取 构造函数的 method id (方法的名称始终为"<init>") (3).创建Java对象的两种方式: (3 ...
- 本地C代码中创建Java对象
作者:唐老师,华清远见嵌入式学院讲师. 创建Java域的对象就是创建Java类的实例,再调用Java类的构造方法. 以Bitmap的构建为例,Bitmap中并没有Java对象创建的代码及外部能访问的构 ...
- 关于protected在子类创建父类对象无法访问父类protected方法或成员
子类(父类的外部包)中访问父类的protetcted属性或者方法,是不可以通过创建父类对象调用的.注意:此处不讨论同包下的父类子类,因为同包下所有类都可访问protected属性或者方法. 请参见Ja ...
- java对象实现深复制的方法
p2 = (Person)org.apache.commons.lang3.ObjectUtils.cloneBean(p); Person p2 = new Person(); p2 = (Pers ...
- 重新 java 对象的 equals 和 hashCode 方法的建议和示例代码
equals 方法 equals 方法需要满足的规范: 自反性: 对于任意非空引用 x, x.equals(x) 应该返回 true; 对称性: 对于任意引用, 当且仅当 x.equals(y) == ...
随机推荐
- Django:学习笔记(8)——视图
Django:学习笔记(8)——视图
- bash 获取时间段内的日志内容
需求,获取时段内的/var/log/messages文件内出现错误的消息,支持多行的消息,支持天,小时分钟,秒级的区间,可以修改监控的日志对象 #!/bin/bash if [ $# != 1 ] ; ...
- vector 迭代 删除指定的元素
std::vector< Bullet * > m_vBullets; std::vector< Bullet * > m_vRemoveBulltes; ){ for ( s ...
- tomcat进程意外退出的问题分析(转)
原文链接:http://hongjiang.info/why-kill-2-cannot-stop-tomcat/ 节前某个部门的测试环境反馈tomcat会意外退出,我们到实际环境排查后发现不是jvm ...
- kivy sdl2 - ImportError: DLL load failed: 找不到指定的模块
from kivy.app import App from kivy.uix.button import Button class TestApp(App): def build(self): ret ...
- oracle 分区表详解
一.分区表的概述: Oracle的表分区功能通过改善可管理性.性能和可用性,从而为各式应用程序带来了极大的好处.通常,分区可以使某些查询以及维护操作的性能大大提高.此外,分区还可以极大简化常见的管理任 ...
- 20145310 《Java程序设计》第7周学习总结
20145310 <Java程序设计>第7周学习总结 教材学习内容总结 本周主要进行第十二章和第十三章的学习. Lambda定义:一个不用被绑定到一个标识符上,并且可能被调用的函数. 在只 ...
- http://www.jb51.net/article/28619.htm
http://www.jb51.net/article/28619.htm js autocomplete 自动完成
- 树梅派配置ad-hoc网络
树梅派配置ad-hoc网络 更新与安装 1.更改源/etc/apt/source.list: http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian ...
- CentOS(64位)安装apr
安装apr来提高tomcat 的可伸缩性和性能 cd /usr/local/ 1. 下载apr 和 apr-util最新版 wget http://apache.fayea.com/apache-m ...