在Java中得到对象一般有两种情况。第一使用new创建,这是经常用的方式;第二使用clone方式,这种方式比较生僻。看过一些文章和书籍,比如《Java程序性能优化:让你的Java程序更快、更稳定》中提到推荐使用clone的方式(第137页)。
下面就这两种方式进行测试:
先来一个User类
- /**
- * 实体类
- * @author chdyan
- * @date 2014-10-20
- * @since jdk1.6
- */
- public class User implements Serializable, Cloneable {
- private static final long serialVersionUID = -1757309588653207550L;
- //用户名
- private String username;
- //密码
- private transient String password;
- //出生日期
- private Date birthDay;
- //地址
- private String address;
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
- public Date getBirthDay() {
- return birthDay;
- }
- public void setBirthDay(Date birthDay) {
- this.birthDay = birthDay;
- }
- public String getAddress() {
- return address;
- }
- public void setAddress(String address) {
- this.address = address;
- }
- @Override
- public Object clone() {
- User user = null;
- try {
- user = (User) super.clone();
- user.username = this.username;
- if(this.birthDay != null)
- user.birthDay = (Date) this.birthDay.clone();
- user.address = this.address;
- } catch (CloneNotSupportedException e) {
- e.printStackTrace();
- }
- return user;
- }
- }
下面进行没有属性值的测试:
- /**
- * @author chdyan
- * @Date 2014-10-20
- */
- public class CloneTest {
- public static void main(String[] args) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
- User user = new User();
- //-----------使用new的方式创建---------------
- long begin = System.nanoTime();
- for(int i=0; i<10000; i++) {
- new User();
- }
- System.out.println("---------------new方式创建:" + (System.nanoTime() - begin));
- //-----------使用clone的方式创建---------------
- begin = System.nanoTime();
- for(int i=0; i<10000; i++) {
- user.clone();
- }
- System.out.println("-------------clone方式创建:" + (System.nanoTime() - begin));
- //-----------使用commons-lang3的SerializationUtils的所谓clone方式创建---------------
- begin = System.nanoTime();
- for(int i=0; i<10000; i++) {
- SerializationUtils.clone(user);
- }
- System.out.println("SerializationUtils方式创建:" + (System.nanoTime() - begin));
- //-----------使用commons-beanutils的BeanUtils的所谓cloneBean方式创建---------------
- begin = System.nanoTime();
- for(int i=0; i<10000; i++) {
- BeanUtils.cloneBean(user);
- }
- System.out.println("---------BeanUtils方式创建:" + (System.nanoTime() - begin));
- }
- }
结果为:
或许会有疑问,user的clone方法里还有赋值呢。当然慢了。那好,我就把User类中的赋值语句去了,改成如下。
- @Override
- public Object clone() {
- User user = null;
- try {
- user = (User) super.clone();
- } catch (CloneNotSupportedException e) {
- e.printStackTrace();
- }
- return user;
- }
看下结果
依旧不是一个数量级的。
测试使用jdk1.6.0.45可以看出,new方式比clone方式快多了。SerializationUtils的clone原理其实是使用了序列化的方式,是最慢的。BeanUtils的cloneBean的原理是创建对象然后给对象的成员变量拷贝值的方式。
空对象,不进行复制,是最快的。
-------------------------------------------------华丽的分隔线-----------------------------------------------------------------------
下面给参数都赋值来测试下,new和clone方式创建对象哪个快,包括增加BeanUtils的copyProperties方法和Properties的copyProperties方法,共同比较下。测试方法如下:
- /**
- * @author chdyan
- * @Date 2014-10-20
- */
- public class CloneTest {
- public static void main(String[] args) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
- Date now = new Date();
- //由于String对象是不可变的。
- String username = "ChdYan";
- String password = "123456";
- String address = "中国,广东";
- User user = new User();
- user.setUsername(username);
- user.setPassword(password);
- user.setBirthDay(now);
- user.setAddress(address);
- //----------------初始化数据------------------------
- int i=0; int j=10000;
- //-----------使用new的方式创建---------------
- User u = null;
- long begin = System.nanoTime();
- for(i=0; i<j; i++) {
- u = new User();
- //由于String对象是不可变的。
- u.setUsername(username);
- u.setPassword(password);
- u.setBirthDay(new Date());
- u.setAddress(address);
- }
- System.out.println("--------------------------new方式创建:" + (System.nanoTime() - begin));
- //-----------使用clone的方式创建---------------
- begin = System.nanoTime();
- for(i=0; i<j; i++) {
- user.clone();
- }
- System.out.println("------------------------clone方式创建:" + (System.nanoTime() - begin));
- //-----------使用commons-lang3的SerializationUtils的所谓clone方式创建---------------
- begin = System.nanoTime();
- for(i=0; i<j; i++) {
- SerializationUtils.clone(user);
- }
- System.out.println("----SerializationUtils的clone方式创建:" + (System.nanoTime() - begin));
- //-----------使用commons-beanutils的BeanUtils的所谓cloneBean方式创建---------------
- begin = System.nanoTime();
- for(i=0; i<j; i++) {
- BeanUtils.cloneBean(user);
- }
- System.out.println("---------BeanUtils的cloneBean方式创建:" + (System.nanoTime() - begin));
- //-----------使用commons-beanutils的BeanUtils的所谓copyProperties方式创建---------------
- begin = System.nanoTime();
- for(i=0; i<j; i++) {
- u = new User();
- BeanUtils.copyProperties(u, user);
- }
- System.out.println("----BeanUtils的copyProperties方式创建:" + (System.nanoTime() - begin));
- //-----------使用commons-beanutils的BeanUtils的所谓copyProperties方式创建---------------
- begin = System.nanoTime();
- for(i=0; i<j; i++) {
- u = new User();
- PropertyUtils.copyProperties(u, user);
- }
- System.out.println("PropertyUtils的copyProperties方式创建:" + (System.nanoTime() - begin));
- }
- }
可以看到每一个对象都已经赋值了,结果如下:
new方式还是要比clone方式快多。如果觉得string对象太多了,可以去User类中增加一两个Date成员变量。通过本人亲自测试,测试结果也一样。
所以,创建对象使用new创建,只是很常见的,jvm也对其进行了深度优化。而clone方式,是比较生僻的使用方法。 数据结果中可以看到BeanUtils的cloneBean和copyProperties时间比较接近,两者是使用共同的拷贝成员变量方法。PropertyUtils的copyProperties的速度比BeanUtils快多了。虽然说手动设置比使用类库拷贝成员方法快些,但是为了通用性,设计的简洁,推荐使用PropertyUtils的copyProperties的拷贝方法
相关推荐
深度克隆对象,不过效率没有显示的new对象快,不过很安全
alibaba.com new PHP clone 英文版阿里巴巴克隆 PHP完整版源码 英文版本的, 老外拿出来卖USD, 这里免费拿来大家学习学习。
本文实例讲述了PHP对象克隆clone用法。分享给大家供大家参考,具体如下: 浅克隆:只是克隆对象中的非对象非资源数据,即对象中属性存储的是对象类型,则会出现克隆不完全 <?php class B{ public $val = 10; } ...
git-clone-init - 从克隆创建新项目 在您的路径中创建一个新的git-clone-init bash 脚本,可用于从 git clone 快速创建新项目。 它的作用的,。 用法 npm install -g git-clone-init # install once # when you want...
深度复制DeepCopy可帮助您创建对象的深层副本(克隆)。 它旨在处理关联图中的循环。目录如何? 使用Composer安装: composer require myclabs/deep-copy 简单使用: use DeepCopy \ DeepCopy ;$ copier = new ...
一般在Java里创建一个对象,有常用的几种方式 正常通过 new 操作符; 反射调用 Class 或 java.lang.reflect.Constructor 的 newInstance()方法 克隆调用现有对象的 clone()方法 反序列化调用 java.io....
pageContext对象提供了对JSP页面内所有的对象及名字空间的访问,也就是说他可以访问到本页所在的SESSION,也可以取本页面所在的application的某一属性值,他相当于页面中所有功能的集大成者,它的本类名也叫...
中型博客克隆 这是使用 , 和构建的克隆。 技术领域 特征 写一个故事 社交登录 查看故事 查看所有故事 关注用户 拍一个故事 安装 Git克隆此仓库。 从终端移入文件夹: cd medium-clone-on-node-reactjs 运行npm ...
darts-clone-java 用Java编写的Double-ARray Trie System克隆。 该库基于称为“快速高效”库的 。入门设置要使用Maven添加依赖项,请使用以下命令: < dependency> < groupId>...
中克隆 这是使用 , 和构建的克隆。 地位 该项目正在重新开发中,以成为我课程学习的主要内容以进行更新 技术领域 特征 写一个故事 社交登录 查看故事 查看所有故事 关注用户 拍一个故事 安装 Git克隆此仓库。 从...
有时候我们想克隆一个List去做别的事,而不影响原来的List,我们直接在list后面加上小点点,发现并没有Clone这样的扩展函数。这时候就只有自己扩展了。 尝试了三种方式,测试都通过了,至于性能方面我还没有做测试。 ...
之后,创建一个新的Corporate_Drone对象,增加employeeid成员的值,克隆这个对象,然后输出一些数据,从而显示克隆对象的tiecolor确实是通过__clone()方法设置的。示例代码: <?php // Create new
地位系统地位特拉维斯 宝石版 代码Climante描述该gem提供了本机实现,可以深度克隆Ruby对象。 它支持Ruby 1.9.3、2.2.x,2.3.x和2.4.x。安装 gem install ruby_deep_clone或将其添加到您的Gemfile gem 'ruby_deep_...
本文实例讲述了JS克隆,属性,数组,对象,函数。分享给大家供大家参考,具体如下: [removed] /* 克隆原型得到对象 */ function clone(object) { function F() {} F.prototype = object; return new F; } var ...
Mongoose 模式克隆 深度克隆并返回模式的副本,向该模式添加关键路径/模式类型对,您还可以添加另一个模式并复制所有路径、虚拟、getter、setter、索引、方法和静态。 特征: 深度克隆模式 复制路径、虚拟、getter...
可读流克隆npm安装可读流克隆使用此实用程序,您可以将可读流传输到多个可写流中节点const fs = require ( "fs" ) ;const ReadableStreamClone = require ( "readable-stream-clone" ) ;const readStream = fs . ...
Spotify克隆 在这个项目中,我将创建Spotify的克隆。 所有最新更新都可以在new-changes分支上看到 分行:
用法下面是一个关于如何使用库的示例 // Example TestObject clone = new ObjectCloner().deepClone(originalTestObject);有关更多示例,请参阅 junit 测试用例。Maven将以下依赖添加到maven项目中 <dependency> ...
介绍php封装的mysqli类,结合实例形式分析了php针对mysqli操作类的定义与使用技巧,掌握满足单例模式的...(3)私有的克隆方法-为了防止在类外通过clone成生另一个对象 (4)公有的静态方法-为了让用户进行实例化对象的操作
将当前工作目录更改为要创建克隆目录的位置。 如果当前位置是您希望项目所在的位置,则保持原样。 输入git clone ,然后粘贴您在第 3 步中复制的 URL。 $ git clone https://github.com/kunmi02/