java中的clone方法的使用

clone方法的使用

什么是clone()

首先看一下jdk中对clone方法的解释:

/**
     * Creates and returns a copy of this object.  The precise meaning
     * of "copy" may depend on the class of the object. The general
     * intent is that, for any object {@code x}, the expression:
     * <blockquote>
     * <pre>
     * x.clone() != x</pre></blockquote>
     * will be true, and that the expression:
     * <blockquote>
     * <pre>
     * x.clone().getClass() == x.getClass()</pre></blockquote>
     * will be {@code true}, but these are not absolute requirements.
     * While it is typically the case that:
     * <blockquote>
     * <pre>
     * x.clone().equals(x)</pre></blockquote>
     * will be {@code true}, this is not an absolute requirement.
     * <p>
     * By convention, the returned object should be obtained by calling
     * {@code super.clone}.  If a class and all of its superclasses (except
     * {@code Object}) obey this convention, it will be the case that
     * {@code x.clone().getClass() == x.getClass()}.
     * <p>
     * By convention, the object returned by this method should be independent
     * of this object (which is being cloned).  To achieve this independence,
     * it may be necessary to modify one or more fields of the object returned
     * by {@code super.clone} before returning it.  Typically, this means
     * copying any mutable objects that comprise the internal "deep structure"
     * of the object being cloned and replacing the references to these
     * objects with references to the copies.  If a class contains only
     * primitive fields or references to immutable objects, then it is usually
     * the case that no fields in the object returned by {@code super.clone}
     * need to be modified.
     * <p>
     * The method {@code clone} for class {@code Object} performs a
     * specific cloning operation. First, if the class of this object does
     * not implement the interface {@code Cloneable}, then a
     * {@code CloneNotSupportedException} is thrown. Note that all arrays
     * are considered to implement the interface {@code Cloneable} and that
     * the return type of the {@code clone} method of an array type {@code T[]}
     * is {@code T[]} where T is any reference or primitive type.
     * Otherwise, this method creates a new instance of the class of this
     * object and initializes all its fields with exactly the contents of
     * the corresponding fields of this object, as if by assignment; the
     * contents of the fields are not themselves cloned. Thus, this method
     * performs a "shallow copy" of this object, not a "deep copy" operation.
     * <p>
     * The class {@code Object} does not itself implement the interface
     * {@code Cloneable}, so calling the {@code clone} method on an object
     * whose class is {@code Object} will result in throwing an
     * exception at run time.
     *
     * @return     a clone of this instance.
     * @throws  CloneNotSupportedException  if the object's class does not
     *               support the {@code Cloneable} interface. Subclasses
     *               that override the {@code clone} method can also
     *               throw this exception to indicate that an instance cannot
     *               be cloned.
     * @see java.lang.Cloneable
     */

看到这里大家可能会很懵逼, 其实clone方法简单来说就是将一个对象的属性和方法都复制一个给另外一个相同类型的对象.注意:复制之后这个对象的地址就和原本对象不同了.

clone的分类

clone 大致分两种,但它们都要实现Cloneable接口,重写clone方法

影子克隆

这个克隆只是简单的将这个对象进行克隆, 不管对象里面有不有引用类的属性, 也就是说,这种克隆 , 它里面的引用类型的成员变量地址还是一样的;

代码分析
public class Person implements Cloneable {

	private String name;
	private int age;

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

	@Override
	public boolean equals(Object obj) {
		Person p = (Person) obj;

		return this.name.equals(p.getName()) && (this.age == p.getAge());
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}

	public static void main(String args) throws CloneNotSupportedException {
		Person p1 = new Person("小宇", 22);
		Person p2 = (Person)p1.clone();
		System.out.println(p1 == p2);
		System.out.println(p1);
		System.out.println(p2);
	}
}

运行结果:

在这里插入图片描述
可以发现clone的p2 和p1的内容是完全相同

深度克隆

代码分析
public class Person implements Cloneable {

	private String name;
	private int age;

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

	@Override
	public boolean equals(Object obj) {
		Person p = (Person) obj;

		return this.name.equals(p.getName()) && (this.age == p.getAge());
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}

}

public class Group implements Cloneable {

	private String groupName;
	private int groupId;
	private Person p;

	public Group(String groupName, int groupId, Person p) {
		super();
		this.groupName = groupName;
		this.groupId = groupId;
		this.p = p;
	}

	public String getGroupName() {
		return groupName;
	}

	public void setGroupName(String groupName) {
		this.groupName = groupName;
	}

	public int getGroupId() {
		return groupId;
	}

	public void setGroupId(int groupId) {
		this.groupId = groupId;
	}

	public Person getP() {
		return p;
	}

	public void setP(Person p) {
		this.p = p;
	}

	@Override
	public boolean equals(Object obj) {
		Group g = (Group) obj;

		return (this.groupId == g.groupId) && this.groupName.equals(g.getGroupName()) && this.p.equals(g.getP());
	}

	@Override
	public String toString() {
		return "Group [groupName=" + groupName + ", groupId=" + groupId + ", p=" + p + "]";
	}

	@Override
	public Object clone() throws CloneNotSupportedException {

		// 深度克隆
		Group group = null;

		try {
			group = (Group) super.clone();
			group.p = (Person) this.p.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}

		return group;
	}

	public static void main(String[] args) throws CloneNotSupportedException {
			Group g = new Group("英语学习小组", 1, new Person("小宇", 22));
			Group gCopy = (Group)g.clone();
			System.out.println(gCopy.equals(g));
			System.out.println(g == gCopy);
			System.out.println(g);
			System.out.println(gCopy);
	
	}
}

运行结果:
在这里插入图片描述
可以发现深度克隆不仅仅对Grop进行了克隆, 对立面的Person同样进行了克隆, 也就是说所有的引用类型的地址都发生了改变;

运用

在编程的过程中当我们遇到需要使用一个引用类型, 但又不想去改变里面的内容的时候我们就可以使用克隆.

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Javaclone()方法是Object类定义的方法,它用于创建并返回当前对象的一个副本。这个副本就是一个新的对象,它与原始对象具有相同的属性和方法。通常情况下,我们需要在一个类实现clone()方法来支持对象的克隆。 克隆对象是在Java处理对象的一种常见方式。通过克隆,我们可以在不修改原始对象的情况下创建该对象的一个副本。这在某些情况下是非常有用的,例如在多线程环境下,我们需要多个线程同时访问同一个对象,但是又不希望它们之间相互干扰。 在Java,要使用clone()方法来实现对象的克隆,我们需要满足两个条件: 1. 实现Cloneable接口:这个接口是一个标记接口,它没有任何方法,只是用来标记一个类可以被克隆。 2. 重写clone()方法:这个方法是Object类的一个protected方法,需要在我们的类进行重写。在重写这个方法时,我们需要调用super.clone()方法来创建一个新的对象,并将原始对象的属性复制到这个新对象。 下面是一个示例代码,演示了如何在Java实现对象的克隆: ``` public class MyClass implements Cloneable { private int value; public MyClass(int value) { this.value = value; } public int getValue() { return value; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } ``` 在这个示例代码,我们实现了一个MyClass类,并重写了clone()方法。在这个方法,我们调用了super.clone()方法来创建一个新的对象,并返回这个新对象。由于我们的类实现了Cloneable接口,因此它可以被克隆。 使用这个类进行克隆的代码如下: ``` MyClass obj1 = new MyClass(10); MyClass obj2 = (MyClass) obj1.clone(); System.out.println(obj1.getValue()); // 输出10 System.out.println(obj2.getValue()); // 输出10 ``` 在这个代码,我们创建了一个MyClass对象obj1,并将其克隆为obj2。由于这两个对象具有相同的属性和方法,因此它们的输出结果也是相同的。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值