java.lang.Object.clone()笔记

clone()可以对对象进行clone,通常我们会想要使用它去克隆一个对象,并且希望改变一个对象所以用的对象,不会对他的克隆体产生影响。
首先看一下clone的源码:

public class Object  {
     ···
     protected native Object clone() throws CloneNotSupportedException;
     ···
}
从中可以看到三个问题:

第一:Object类的clone()方法是一个native方法,native方法的效率一般来说都是远高于Java中的非native方法。
第二:Object中的clone()方法被protected修饰符修饰,这意味着子类只能调用受保护的clone方法克隆他自己,而无法在一个类里面克隆另一个类。而且,直接调用Object的clone实现的仅仅是浅克隆,为此,必须在子类中重新定义clone方法,并将它声明为public,这样可以就可以在任何地方实现满足我们需求的(深克隆或者浅克隆)对象的克隆。
第三:Object的clone()返回的是一个Object对象。
第四:Object在这里没有提供任何基础实现,同时看Cloneable接口,java规定如果没有实现该接口,那么我们试图调用clone方法会抛出 java.lang.CloneNotSupportedException错误,所以我们可以看出clone是个特殊的方法。。他的基础克隆是怎么实现的,我们并不知道,只知道super.clone()方法返回的是一个原对象的浅克隆Object。

package java.lang;

/**
 * A class implements the Cloneable interface to
 * indicate to the {@link java.lang.Object#clone()} method that it
 * is legal for that method to make a
 * field-for-field copy of instances of that class.
 * 

* Invoking Object's clone method on an instance that does not implement the * Cloneable interface results in the exception * CloneNotSupportedException being thrown. *

* By convention, classes that implement this interface should override * Object.clone (which is protected) with a public method. * See {@link java.lang.Object#clone()} for details on overriding this * method. *

* Note that this interface does not contain the clone method. * Therefore, it is not possible to clone an object merely by virtue of the * fact that it implements this interface. Even if the clone method is invoked * reflectively, there is no guarantee that it will succeed. * * @author unascribed * @see java.lang.CloneNotSupportedException * @see java.lang.Object#clone() * @since JDK1.0 */ public interface Cloneable { }

关于浅克隆与深克隆:
浅克隆:浅克隆是指仅仅按值进行克隆,对于对象,相当于被克隆者与克隆者有着相同的引用。
深克隆:所有变量有着与原来对象相同的值,对于引用其他对象的变量将会指向一个新的被复制的对象。
关于第二点中的protected修饰符:

protected修饰符的访问权限有些微妙,是本包和它的子类,但是有一点需要注意的是如果有两个类都是另一个类的子类,那么其中一个子类是不能在另一个子类中直接访问父类中的protected方法的

解决三个问题我们需要:

1.在子类中实现Cloneable接口
2.在子类中重载clone,并将他声明为public
3.在子类中调用super.clone(),然后根据需求,自定义子类的clone方法。

Core java中的clone()方法示例:

    @Override
    public Employee clone() throws CloneNotSupportedException {
        Employee e1 = (Employee) super.clone();
        e1.hireDay = (Date) hireDay.clone();
        return e1;
        
    }

测试结果:

    public static void main(String[] args) throws CloneNotSupportedException {
        Employee e1 = new Employee("Tom", 2000, 1996, 5, 2);
        Employee e2 = (Employee) e1.clone();
        System.out.println(e2.getName());
        e2.setName("Ted");
        System.out.println(e1.getName());
        System.out.println(e2.getName());   
        System.out.println(e1.getHireDay());    //Thu May 02 00:00:00 CST 1996
        System.out.println(e2.getHireDay());    //Thu May 02 00:00:00 CST 1996
        e1.getHireDay().setMonth(10);
        System.out.println(e1.getHireDay());    //Sat Nov 02 00:00:00 CST 1996
        System.out.println(e2.getHireDay());    //Thu May 02 00:00:00 CST 1996
    }

你可能感兴趣的:(java.lang.Object.clone()笔记)