`

利用clone来克隆对象

 
阅读更多
谈到对象克隆,有人说:我直接把一个对象赋给另外一个对象不就是克隆了吗?
这样做其实是不对的,因为如果是简单赋值的话,这2个对象会指向同一块内存区域,
这样的话,改变一个对象的变量也将会改变另一个。

我们下面来举个例子,看一下是不是这样。

我们先做一个Employee类,代码如下:
package corejava2.objects;

import java.util.*;

public class Employee {
	private String name;
	private double salary;
	private Date hireDay;

	public Employee(String name, double salary) {
		this.name = name;
		this.salary = salary;
	}

	public void setHireDay(int year, int month, int day) {
		// GregorianCalendar是指阳历时间
		hireDay = new GregorianCalendar(year, month - 1, day).getTime();
	}

	public void raiseSalary(double byPercent) {
		double raise = salary * byPercent / 100;
		salary += raise;
	}

	public String toString() {
		return "Employee[name=" + name + ",salary=" + salary + ",hireDay="
				+ hireDay + "]";
	}
}


然后,我们做一个客户端代码用来测试下简单拷贝会是什么样子,代码如下:
package corejava2.basic.clone;

import corejava2.objects.*;

public class CopyTest {
	public static void main(String[] args) {
		Employee original = new Employee("David Anthony", 50000); 
		Employee copy = original;
		
	  original.setHireDay(2008, 1, 1);
	  copy.raiseSalary(10);
	  
	  System.out.println("original: " + original);
	  System.out.println("copy: " + copy);
	}
}


输出结果:
original: Employee[name=David Anthony,salary=55000.0,hireDay=Tue Jan 01 00:00:00 CST 2008]
copy: Employee[name=David Anthony,salary=55000.0,hireDay=Tue Jan 01 00:00:00 CST 2008]


我们可以看到,original对象和copy对象的工资是一样的,这样是不对的,因为我们只是增加了original的工资,那么要怎样解决呢?只有利用克隆。

新的代码如下:

首先,我们需要改造下Employee类,让它能支持克隆,如下:
package corejava2.objects;

import java.util.*;

public class Employee implements Cloneable {
	private String name;
	private double salary;
	private Date hireDay;

	public Employee(String name, double salary) {
		this.name = name;
		this.salary = salary;
	}

	public Employee Clone() throws CloneNotSupportedException {
		// call Object.clone()
		Employee cloned = (Employee) super.clone();

		// clone mutable fields
		cloned.hireDay = (Date) hireDay.clone();

		return cloned;
	}

	public void setHireDay(int year, int month, int day) {
		// GregorianCalendar是指阳历时间
		hireDay = new GregorianCalendar(year, month - 1, day).getTime();
	}

	public void raiseSalary(double byPercent) {
		double raise = salary * byPercent / 100;
		salary += raise;
	}

	public String toString() {
		return "Employee[name=" + name + ",salary=" + salary + ",hireDay="
				+ hireDay + "]";
	}
}


接着,我们写下客户端代码:
package corejava2.basic.clone;

import corejava2.objects.Employee;

public class CloneTest {
	public static void main(String[] args) {
		try {
			Employee original = new Employee("David Anthony", 50000);
			original.setHireDay(2008, 1, 1);
			Employee clone = original.Clone();
			
			original.raiseSalary(10);

			System.out.println("original: " + original);
			System.out.println("clone: " + clone);
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}	
	}
}


输出结果:
original: Employee[name=David Anthony,salary=55000.0,hireDay=Tue Jan 01 00:00:00 CST 2008]
clone: Employee[name=David Anthony,salary=50000.0,hireDay=Tue Jan 01 00:00:00 CST 2008]


可以看到这时工资不一样了。

需要注意的是:默认的克隆操作,即从Object继承过来的是浅拷贝,如果我们的类中有其他对象,也就是非基本类型的成员,我们需要重写Clone()方法。

分享到:
评论

相关推荐

    clone 深度克隆对象

    "clone"方法就是用于复制对象的一种方式,尤其在Java等支持此功能的语言中。本文将深入探讨"深度克隆"这一概念,以及它与普通克隆的区别,并讨论其在实际应用中的优缺点。 深度克隆,也称为完全克隆,是一种创建新...

    java 对象克隆

    在Java编程语言中,对象克隆是一种创建一个与原对象具有相同数据的新对象的过程。...对于更复杂的场景,可以自定义克隆逻辑或利用序列化来实现深克隆。理解并正确应用这些概念对于开发复杂的Java应用程序至关重要。

    java中的指针,引用及对象的clone

    Java中的对象克隆可以通过实现`Cloneable`接口并覆盖`clone()`方法来完成。对象的克隆分为浅拷贝和深拷贝两种形式。 **1. 浅拷贝** 浅拷贝是指创建一个新的对象,然后将原对象的所有非引用类型的成员变量复制到新...

    clone()示例源码

    在Java编程语言中,`clone()`方法是一个非常重要的概念,特别是在处理对象复制和克隆时。这个方法源自`Object`类,是所有Java类的基类。`clone()`的使用通常涉及到深度复制和浅复制的概念,这两者在数据结构和内存...

    java不同对象及集合的多次复制

    - **浅拷贝**:创建一个新的对象,只复制对象的引用,不复制内部引用的对象。这意味着改变其中一个对象的内部引用对象,会影响另一个对象。 - **深拷贝**:创建一个全新的对象,不仅复制对象本身,还递归复制其...

    MyBatisDemo && JAVA把一个对象的全部属性复制到另一个相同的对象

    深拷贝不仅复制对象,还复制对象中引用的对象。在描述中提到的方法,很可能是关于深拷贝的实现。 在Java中,我们可以通过以下几种方法实现对象的深拷贝: 1. **实现Serializable接口**:利用序列化和反序列化来...

    Javascript对象Clone实例分析

    这在需要复制对象状态的场景中非常有用,比如在数据处理、单元测试等领域。 文章中提供的克隆函数`Clone`被添加到`Object.prototype`上,这意味着所有对象默认都会继承这个方法。这个克隆函数的实现包含以下几个...

    Java利用序列化实现对象深度clone的方法

    总的来说,Java序列化提供了一种实现对象深度克隆的方法,适用于需要完整复制对象及其关联对象的情况。然而,这也带来了一些潜在问题,如性能影响、安全风险(因为序列化的对象可能被恶意用户反序列化以执行代码)...

    编程回忆_利用克隆创建物体

    "编程回忆_利用克隆创建物体"这个主题,正是探讨如何在Unity中通过编程方式实现对象的克隆。 首先,我们需要了解Unity中的`GameObject`类,它是所有游戏对象的基础,包含了位置、旋转、缩放等属性,以及组件...

    MSN Messenger Clone

    总的来说,"MSN Messenger Clone"项目涵盖了C#编程语言、.NET框架以及WinForms GUI开发的多个方面,对开发者的技术要求较高,同时也是一个学习和实践网络通信、多线程编程以及UI设计的好案例。通过这个项目,开发者...

    PHP编程中的__clone()方法使用详解

    这展示了如何利用 `__clone()` 来改变克隆对象的状态,而不是简单地复制原始对象的所有属性。 接下来,代码演示了如何克隆对象并改变克隆对象的 `employeeid`,这表明即使在克隆后,两个对象也可以独立地拥有不同的...

    C#视频-面向对象设计模式纵横谈(6):Prototype 原型模式(创建型模式)

    不过需要注意的是,`ICloneable.Clone()`方法默认只提供浅复制,即复制对象的引用,而不是对象的内容。如果需要深度复制(即复制对象内部的所有嵌套对象),则需要在实现`Clone()`方法时进行额外处理。 ```csharp ...

    PHP对象相关知识总结

    在上述例子中,`SubObject`类的`__clone()`方法使得每次复制`SubObject`时,`instance`属性都会递增,从而区分原始对象和复制对象。 最后,我们注意到`cloneTest()`方法的调用。在PHP中,复制的对象会保留原对象的...

    java四种创建对象的方式

    克隆方法创建对象是指利用对象自身的clone方法创建一个与原来对象内容相同的对象。这种方式不会调用原对象的构造方法。为了让一个类支持克隆操作,该类需要实现Cloneable接口。实现Cloneable接口的clone方法需要抛出...

    prototypeAndCreate.zip

    浅度克隆仅仅复制对象本身,而不复制其引用的对象,而深度克隆则会递归地复制对象及其引用的所有对象。 浅度克隆(Shallow Clone): 在Java中,当一个对象实现了`Cloneable`接口并且调用`clone()`方法时,如果对象...

    设计模式——原型模式

    原型模式(Prototype Pattern)是一种创建型设计模式,它允许我们通过复制现有的对象来创建新对象,而无需知道具体创建过程的细节。这种模式的核心在于,它提供了一种对象克隆的简便方法,使得对象的创建过程对用户...

    prototype.rar

    `Cloneable`接口是Java中用于实现原型模式的标准机制,一个类如果实现了这个接口,那么就可以调用其`clone()`方法来复制对象。 在具体实现中,我们首先需要定义一个接口或抽象类,声明`clone()`方法。然后,让需要...

    深度克隆的事例代码

    总结来说,深度克隆是通过复制对象及其所有嵌套的对象来创建一个完全独立的新对象的过程。在不同的编程语言中,实现方式有所不同,但核心思想都是递归地复制对象的属性和子对象。在实际开发中,理解并正确使用深度...

    C#面向对象设计模式纵横谈(5)

    这通常涉及到浅复制(仅复制对象自身的引用)或深复制(复制对象及所有嵌套对象)。 ```csharp public class ConcretePrototype : Prototype { public string Property { get; set; } public ConcretePrototype ...

Global site tag (gtag.js) - Google Analytics