不使用构造方法创建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) == ...
随机推荐
- 关于http响应状态码
http状态返回代码 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码. http状态返回代码 代码 说明 100 (继续) 请求者应当继续提出请求. 服务器返回此代码表示已 ...
- cocos2dx lua invalid 'cobj' in function 'lua_cocos2dx‘ 躺坑
for 循环中保存了创建的 Node节点到 userdata 数据结构中 再次引用发现 一直报 LUA ERROR: [string ".\framework/cocos2dx/NodeEx ...
- Lua 数学类
数学类主要有Vec2(坐标向量).Size(尺寸).Rect(矩形). 创建 在Lua中创建的 Vec2.Size.Rect 都是一个table类型. 其中只有相应的成员变量,没有相关的函数运算. c ...
- quartz (一) 基于 Quartz 开发企业级任务调度应用
本文转自:http://www.ibm.com/developerworks/cn/opensource/os-cn-quartz/ Quartz 基本概念及原理 Quartz Scheduler 开 ...
- redis 简单命令操作
一.概述: 在该系列的前几篇博客中,主要讲述的是与Redis数据类型相关的命令,如String.List.Set.Hashes和Sorted-Set.这些命令都具有一个共同点,即所有的操作都是针对与K ...
- selenim之ActionChains 用法
常见的点击方法集锦: 参数: 1.driver是我们的浏览器 2.Actions是我们系统内置的执行鼠标一系列操作的对象 鼠标左击:Actions actions=new Actions(driver ...
- JS的魅力
一.初探JavaScript魅力 基本知识: JavaScript是什么 网页特效原理 -JavaScript就是修改样式 编写JS流程 - 布局:HTML + CSS - 属性:确定修改哪些属性 - ...
- ubuntu 14.04 163镜像
1.备份原来/etc/apt/sources.list 2.以下内容覆盖原来文件内容 deb http://mirrors.163.com/ubuntu/ trusty main restricted ...
- opencv图像处理之在手机上实现背景虚化
http://m.blog.csdn.net/blogercn/article/details/75004162 1.高端数码相机都具有背景虚化功能.背景虚化就是使景深变浅,使焦点聚集在主题上.一般的 ...
- JS变量比较陷阱
我们觉得JS简单是因为它是弱类型的语言,不像java那样对对类型那样敏感,但js也有其不尽人意的地方. 在java中我们无法将数字与字符串直接比较,而js能,而且能直接转换成数值比较,但是如果是字符串 ...