`
ncs123
  • 浏览: 103425 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Cloneable 和 clone()的总结和使用

    博客分类:
  • J2SE
阅读更多
一.Cloneable 的用途
  Cloneable和Serializable一样都是标记型接口,它们内部都没有方法和属性,implements Cloneable表示该对象能被克隆,能使用Object.clone()方法。如果没有implements Cloneable的类调用Object.clone()方法就会抛出CloneNotSupportedException。

二.克隆的分类
  (1)浅克隆(shallow clone),浅拷贝是指拷贝对象时仅仅拷贝对象本身和对象中的基本变量,而不拷贝对象包含的引用指向的对象。
  (2)深克隆(deep clone),深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。

举例区别一下:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2,A2中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2中包含对C2(C1的copy)的引用。

三.克隆的举例
  要让一个对象进行克隆,其实就是两个步骤:
  1. 让该类实现java.lang.Cloneable接口;
  2. 重写(override)Object类的clone()方法。

public class Wife implements Cloneable {
	private int id;
	private String name;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Wife(int id,String name) {
		this.id = id;
		this.name = name;
	}

	@Override
	public int hashCode() {//myeclipse自动生成的
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {//myeclipse自动生成的
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Wife other = (Wife) obj;
		if (id != other.id)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	@Override
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

	/**
	 * @param args
	 * @throws CloneNotSupportedException 
	 */
	public static void main(String[] args) throws CloneNotSupportedException {
		Wife wife = new Wife(1,"wang");
		Wife wife2 = null;
		wife2 = (Wife) wife.clone();
		System.out.println("class same="+(wife.getClass()==wife2.getClass()));//true
		System.out.println("object same="+(wife==wife2));//false
		System.out.println("object equals="+(wife.equals(wife2)));//true
	}
}


四.浅克隆的举例
public class Husband implements Cloneable {
	private int id;
	private Wife wife;
	
	public Wife getWife() {
		return wife;
	}

	public void setWife(Wife wife) {
		this.wife = wife;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public Husband(int id) {
		this.id = id;
	}

	@Override
	public int hashCode() {//myeclipse自动生成的
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		return result;
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

	@Override
	public boolean equals(Object obj) {//myeclipse自动生成的
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Husband other = (Husband) obj;
		if (id != other.id)
			return false;
		return true;
	}

	/**
	 * @param args
	 * @throws CloneNotSupportedException 
	 */
	public static void main(String[] args) throws CloneNotSupportedException {
		Wife wife = new Wife(1,"jin");
		Husband husband = new Husband(1);
		Husband husband2 = null;
		husband.setWife(wife);
		husband2 = (Husband) husband.clone();
		System.out.println("husband class same="+(husband.getClass()==husband2.getClass()));//true
		System.out.println("husband object same="+(husband==husband2));//false
		System.out.println("husband object equals="+(husband.equals(husband)));//true
		System.out.println("wife class same="+(husband.getWife().getClass()==husband2.getWife().getClass()));//true
		System.out.println("wife object same="+(husband.getWife()==husband2.getWife()));//true
		System.out.println("wife object equals="+(husband.getWife().equals(husband.getWife())));//true
	}
}


五.深克隆的举例
  如果要深克隆,需要重写(override)Object类的clone()方法,并且在方法内部调用持有对象的clone()方法;注意如下代码的clone()方法
public class Husband implements Cloneable {
	private int id;
	private Wife wife;
	
	public Wife getWife() {
		return wife;
	}

	public void setWife(Wife wife) {
		this.wife = wife;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public Husband(int id) {
		this.id = id;
	}

	@Override
	public int hashCode() {//myeclipse自动生成的
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		return result;
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		Husband husband = (Husband) super.clone();
		husband.wife = (Wife) husband.getWife().clone();
		return husband;
	}

	@Override
	public boolean equals(Object obj) {//myeclipse自动生成的
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Husband other = (Husband) obj;
		if (id != other.id)
			return false;
		return true;
	}

	/**
	 * @param args
	 * @throws CloneNotSupportedException 
	 */
	public static void main(String[] args) throws CloneNotSupportedException {
		Wife wife = new Wife(1,"jin");
		Husband husband = new Husband(1);
		Husband husband2 = null;
		husband.setWife(wife);
		husband2 = (Husband) husband.clone();
		System.out.println("husband class same="+(husband.getClass()==husband2.getClass()));//true
		System.out.println("husband object same="+(husband==husband2));//false
		System.out.println("husband object equals="+(husband.equals(husband)));//true
		System.out.println("wife class same="+(husband.getWife().getClass()==husband2.getWife().getClass()));//true
		System.out.println("wife object same="+(husband.getWife()==husband2.getWife()));//false
		System.out.println("wife object equals="+(husband.getWife().equals(husband.getWife())));//true
	}
}

但是也有不足之处,如果Husband内有N个对象属性,突然改变了类的结构,还要重新修改clone()方法。解决办法:可以使用Serializable运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。

参考java创建对象的第四种方法:
http://ncs123.iteye.com/blog/1775661
分享到:
评论

相关推荐

    java Clone

    总之,Java的`clone`机制提供了复制对象的能力,通过实现`Cloneable`接口和覆盖`clone`方法,我们可以创建对象的副本,同时保证原对象不受影响。根据需求的不同,可以选择浅克隆或深克隆来处理对象及其引用的复杂性...

    java clone

    总结来说,Java中的`clone`方法是一种快速创建对象副本的手段,但它需要谨慎使用,特别是在处理包含复杂数据结构的对象时。理解其工作原理,以及何时和如何正确地使用`clone`,对于提升代码质量和效率至关重要。在...

    clone()示例源码

    `clone()`的使用通常涉及到深度复制和浅复制的概念,这两者在数据结构和内存管理中扮演着关键角色。 首先,让我们理解`clone()`的基本用法。`clone()`方法创建并返回一个当前对象的副本,新创建的对象与原对象具有...

    java_clone用法

    它属于`Object`类的一部分,但需要显式地在子类中声明并实现`Cloneable`接口才能正常使用。本文将详细介绍`clone`的基本概念、工作原理以及如何实现浅拷贝和深拷贝。 #### 二、预备知识 在深入了解`clone`之前,...

    java clone的小例子

    要使用`clone()`方法,一个类需要实现`Cloneable`接口。这个接口没有定义任何方法,但它的存在表明这个类允许被克隆。如果一个类没有实现`Cloneable`接口,然后尝试调用`clone()`,系统会抛出`...

    Java深浅clone

    在Java编程语言中,`Cloneable`接口和`clone()`方法是两个重要的概念,它们用于对象复制。在本文中,我们将深入探讨Java中的浅克隆(shallow clone)和深克隆(deep clone),并结合测试代码进行分析。 首先,让...

    clone()方法示例(对象克隆)_对象克隆_nervouse78_源码

    在实际编程中,除了`clone()`方法,还可以考虑使用`Serializable`接口结合`ObjectInputStream`和`ObjectOutputStream`实现序列化和反序列化来创建对象的深拷贝。这种方法虽然相对复杂,但对于复杂对象结构的完全复制...

    Clone详解.doc

    - 实现`Cloneable`接口是调用`clone()`的前提,否则会抛异常。 - 重写`clone()`方法时,需要处理非基本类型的成员变量,确保它们也能够被正确地复制。 总的来说,Java中的克隆机制提供了复制对象的能力,这在很多...

    关于java clone的一些基本的概念

    总结一下,Java中的`clone`方法是实现对象复制的一种方式,涉及到浅拷贝和深拷贝的概念。理解并正确使用`clone`对于编写可维护、可扩展的代码至关重要。在实际应用中,根据需求选择合适的复制策略,并注意处理可能...

    Java中clone方法共6页.pdf.zip

    本资料"Java中clone方法共6页.pdf.zip"可能包含了关于如何理解和使用`clone()`方法的详细解释,以及它在实际开发中的应用示例。 `clone()`方法的主要用途是创建一个现有对象的副本,这个副本与原始对象具有相同的...

    clone 深度克隆对象

    实现深度克隆可以采用实现Cloneable接口并重写clone(),或者利用序列化和反序列化技术,具体选择取决于应用场景和性能需求。在实际项目中,应根据具体情况权衡效率和安全性,合理选择克隆策略。

    学习Java实验7抽象类和接口.pdf

    本实验主要讲解了Java中的抽象类和接口的概念和使用方法,并且深入探讨了 Cloneable 接口和 clone 方法在对象内容复制中的应用。 一、抽象类的概念和使用方法 在 Java 中,抽象类是一个不能被实例化的类,它提供了...

    Java Clone深拷贝与浅拷贝的两种实现方法

    深拷贝可以使用多种方法来实现,例如使用序列化和反序列化、使用复制构造函数、使用 clone() 方法等。 例如,我们可以使用下面的代码来实现深拷贝: ```java public class Student implements Cloneable { ...

    clone type

    标题中的"clone type"指的是在编程中的一种复制对象的方式,特别是与Java语言中的`clone()`方法...不过,根据标题和描述,我们可以推断出博客文章可能涵盖了如何在Java编程中正确使用和理解`clone type`的各个方面。

    Java中的深拷贝(深复制)和浅拷贝(浅复制) 示例代码

    深拷贝可以通过序列化和反序列化实现,或者手动实现Cloneable接口并重写`clone()`方法。 示例代码(使用序列化): ```java import java.io.*; class MyClass implements Serializable { int a; String b; ...

    Java的clone方法[归类].pdf

    理解对象复制和引用传递的概念对于避免意外的数据修改至关重要,而正确地使用`clone()`方法可以有效地实现这一目标。在实际开发中,我们还需要考虑深复制和浅复制的区别,以及如何根据需求定制`clone()`方法以满足...

    Java Clone(类的复制)实例代码

    总结来说,Java的`clone()`方法用于创建一个现有对象的副本。实现深复制时,需要确保所有引用的对象都进行复制,防止原始对象和副本之间的共享状态。通过自定义`clone()`方法并适当处理类的成员变量,我们可以有效地...

    31.3、深复制和浅复制clone1

    在Java中,实现深复制通常需要通过实现`Cloneable`接口并重写`clone()`方法来完成。`Object`类中的`clone()`方法默认是受保护的,因此我们需要显式地使其可访问,并在子类中覆盖它。在实现`Cloneable`接口后,我们...

    java 中clone()的使用方法

    在 Java 语言中,有两种方式可以创建对象:使用 new 操作符和使用 clone() 方法。new 操作符的本意是分配内存,程序执行到 new 操作符时,首先需要看 new 操作符后面的类型,因为知道了类型,才能知道要分配多大的...

Global site tag (gtag.js) - Google Analytics