在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的拷贝方法
相关推荐
这意味着如果一个对象中包含了其他对象的引用,深度克隆会创建这些引用对象的独立副本,而不是简单地复制引用。因此,即使原始对象被修改,深克隆后的副本也不会受到影响,从而提供了数据安全性。 在Java中,实现...
但是,需要注意的是,`clone()`方法返回的是一个浅拷贝,即如果对象的属性包含其他对象引用,那么这两个对象引用指向的是同一块内存空间,而不是完全独立的副本。 在`nervouse78`的这个示例中,作者"初生不惑"可能...
2. 深克隆:深克隆旨在创建一个与原始对象完全独立的副本,包括其内部引用的对象。如果一个对象包含对可变(非静态)对象的引用,深克隆会递归地克隆这些内部对象,确保新对象内部的引用指向新的、独立的对象副本。...
Java提供了两种主要的克隆方式:浅克隆(Shallow Clone)和深克隆(Deep Clone)。下面我们将深入探讨这两种克隆方法。 ### 浅克隆 浅克隆是指创建一个新的对象,其成员变量的值与原对象相同,但引用类型成员变量...
在上面的代码中,我们创建了一个 A 对象 t1,然后使用 Clone 方法将其复制到另一个对象 t2 中。我们可以看到,t2 中的字段值都是 t1 的副本。然后,我们修改了 t2 中的字段值,但 t1 中的字段值保持不变。 结论 在...
总之,Java中的对象复制与克隆是程序设计中重要的概念,它提供了创建对象副本的能力,而不会影响原始对象的状态。浅拷贝适用于简单的对象,而深拷贝则用于处理复杂的数据结构,确保对象之间的独立性。在实际应用中,...
首先,Unity3D提供了两种主要的克隆方式:`Instantiate`函数和克隆实例化。`Instantiate`是Unity内置的函数,可以用于创建对象的副本。在提供的部分内容中,我们可以看到一个使用`Instantiate`的例子,克隆了一个名...
在Java编程语言中,克隆是一种创建对象副本的方法,它允许我们复制一个对象并得到一个与原对象相同但独立的新对象。克隆分为两种主要类型:深克隆和浅克隆。理解这两种克隆的区别是Java面向对象编程中的重要概念。 ...
Java中创建对象主要有四种显式的方式,分别是使用new关键字、反射机制、克隆克隆方法以及反序列化手段。每种方法都有其特定的使用场景和特点,以下是这些方法的详细说明: 1. 使用new关键字创建对象 这是最常见也是...
在Java编程语言中,克隆是创建一个对象副本的过程,这个副本与原对象有相同的属性值,但作为不同的对象存在。克隆分为两种主要类型:浅克隆(Shallow Clone)和深克隆(Deep Clone)。这篇博客文章将探讨这两种克隆...
在Java编程语言中,对象克隆是一种创建一个与原对象具有相同数据的新对象的过程。对象克隆主要用于复制或备份对象,以便在不干扰原始对象的情况下对其进行修改或操作。本篇文章将详细探讨Java中的对象克隆及其实现...
【标题】"alibaba.com new PHP clone 英文版阿里巴巴克隆 PHP完整版源码" 涉及的核心知识点主要集中在PHP编程语言、网站克隆技术以及阿里巴巴网站的架构和功能模仿。这个项目是一个用于教学目的的开源版本,旨在帮助...
标题中的“java对象复制克隆”主要涉及的是深拷贝,这是一种创建一个新对象的方式,新对象不仅复制了原对象的所有属性,还复制了嵌套的对象引用,使得修改复制后的对象不会影响到原始对象。 **浅拷贝**:在浅拷贝中...
通过这两个工具,我们可以创建对象的副本,同时根据需要调整克隆对象的状态。在特定情况下,如实现单例模式,我们还可以控制是否允许对象被克隆。理解和熟练运用这些机制,有助于编写更灵活、更高效的代码。
但需要注意的是,`clone()`方法默认执行的是浅克隆,因此如果对象中包含对其他对象的引用,这些引用不会被复制。为了实现深度克隆,我们需要手动处理这些引用,通常通过序列化和反序列化的方式。 以下是实现深度...
在Java中,深度克隆是一种用于创建对象副本的方法,它可以确保复制出的新对象与原对象之间没有任何引用关系,也就是说,新对象中的所有成员变量(包括引用类型)都是原对象对应成员变量的副本。这种特性使得深度克隆...
浅克隆是指创建一个新对象,它的字段与原始对象的字段具有相同的引用。这意味着,如果对象的字段包含可变对象(如数组或集合),那么修改副本的这些字段也会影响原始对象,因为它们共享同一个内存引用。 深克隆则是...
总之,`clone()`方法在Java中提供了对对象复制的基本支持,尤其适用于需要创建对象副本的情况。然而,由于其浅拷贝的特性,开发者需要根据具体需求来决定是否使用它,或者选择其他复制策略,比如序列化和反序列化,...