理论上Object类是所有类的父类,所有类都直接或间接的继承java.lang.Object类。因此省略了extends Object关键字。
Object类中具体方法如下图所示:
其中,部分绿色小锁子图标,如:getClass()、notify()、notifyAll()、wait()等代表该方法被定义为final类型,故不能重写。
补充:
可以通过Alt + 7 快捷键来打开查询一个类的结构。
或通过IDEA中View --> Tool Windows --> Structure 来打开,如下图所示。
Clone方法是一种复制方法,当Clone方法被对象调用,就会复制对象。
复制对象的步骤:
分配内存:分配一个和源对象大小相同的内存空间。
填充域:使用原对象中的各个域。来填充新对象的域。
返回新对象:clone方法返回一个新的、与源对象相同的对象,同样得将这个新对象的引用发布到外部。
Clone方法 不是简单的复制一下参数,而是一种新的对象的创建,通过新对象的创建实现了复制对象参数值的改变不会影响源对象的参数值。Clone方法的创建,如下图所示。
其中,调用Clone方法的对象所属类必须实现Clonable接口且重写接口Clone方法。
Clone方法的调运,如下图所示。
更改Clone方法复制对象中的属性,与原对象的属性相比,如下图所示。
上示图片也进一步的说明了Clone方法 不是简单的复制一下参数,而是一种新的对象的创建。
注:在使用调用Clone方法时,要在main方法中抛出异常,如上图所示。当然在main方法中使用try-catch语句处理异常也可以,如下图所示。
上述中,Clone方法在表层上实现了新对象的创建,保证了复制对象参数值的改变不会影响源对象的参数值。但在实际应用中,除了传递基本类型参数,还会出现所传参数为引用类型的情况,针对这种情况,Object类中默认的Clone方法(浅拷贝)显得有些捉襟见肘,因为它仅仅是简单地执行域对域的copy。故,需要采用深拷贝的方法,即除了调用父类中的Clone方法得到新的对象, 还要将该类中的引用变量也Clone出来。如下图所示。
注:上图只展示了CloneMethod1对象引用Test对象,若Test对象还要引用其他对象,以此类推。
内存中的情景图,如下图所示。
附实现代码:
public class CloneMethod1 implements Cloneable { ? ?//定义test变量 ? ?public Test test; ? ?//构造方法,传入test变量的值 ? ?public CloneMethod1(Test test){ ? ? ? ?this.test = test; ? } ? ?//重写clone方法 ? ?//实现深复制 ? ?@Override ? ?protected Object clone() throws CloneNotSupportedException { ? ? ? ?CloneMethod1 cloneMethod1 = (CloneMethod1) super.clone(); ? ? ? ?//对引用变量也进行复制 ? ? ? ?cloneMethod1.test = (Test) test.clone(); ? ? ? ?return cloneMethod1; ? } } class Test implements Cloneable{ ? ?//Test类中重写clone方法 ? ?@Override ? ?protected Object clone() throws CloneNotSupportedException { ? ? ? ?return super.clone(); ? } } ?
运行类:
public class Application { ? ?public static void main(String[] args) throws CloneNotSupportedException{ ? ? ? ?//构造一个CloneMethod1类的新对象 ? ? ? ?CloneMethod1 cloneMethod1 = new CloneMethod1(new Test()); ? ? ? ?//进行深度复制 ? ? ? ?CloneMethod1 cloneMethod1Copy = (CloneMethod1) cloneMethod1.clone(); ? ? ? ?//输出结果 ? ? ? ?//地址不同说明:复制结果产生了一个新对象 ? ? ? ?System.out.println(cloneMethod1); ? ? ? ?System.out.println(cloneMethod1Copy); ? ? ? ?System.out.println("cloneMethod1 == cloneMethod1Copy : " + (cloneMethod1 == cloneMethod1Copy) ); ? ? ? ?//内部引用变量的地址也不同,说明进行了深复制 ? ? ? ?System.out.println(cloneMethod1.test); ? ? ? ?System.out.println(cloneMethod1Copy.test); ? ? ? ?System.out.println("cloneMethod1.head == cloneMethod1Copy.head : " + (cloneMethod1.test == cloneMethod1Copy.test)); ? } }
在Object中,Clone()是被声明为protected形式的。以前图中CloneMethod1类为例,通过声明为此种类型,可以保证只有在CloneMethod1类里面才能进行CloneMethod1类对象的创建。
在实际情况中,根据具体对象的域是什么情况,来选择是使用浅复制还是深复制。依据原则:基本类型使用浅复制,引用类型使用深复制。