下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

java中实用Object.clone的效果

作者:课课家教育     来源: http://www.kokojia.com点击数:745发布时间: 2016-02-21 16:18:47

标签: Java的继承Java的对象Java的基础类

大神带你学编程,欢迎选课

  调用Object.clone()时,实际发生的是什么事情呢?当我们在自己的类里覆盖clone()时,什么东西对于super.clone()来说是最关键的呢?根类中的clone()方法负责建立正确的存储容量,并通过“按位复制”将二进制位从原始对象中复制到新对象的存储空间。也就是说,它并不只是预留存储空间以及复制一个对象——实际需要调查出欲复制之对象的准确大小,然后复制那个对象。由于所有这些工作都是在由根类定义之clone()方法的内部代码中进行的(根类并不知道要从自己这里继承出去什么),所以大家或许已经猜到,这个过程需要用RTTI判断欲克隆的对象的实际大小。采取这种方式,clone()方法便可建立起正确数量的存储空间,并对那个类型进行正确的按位复制。

java中实用Object.clone的效果_Java的继承_Java的对象_课课家

  不管我们要做什么,克隆过程的第一个部分通常都应该是调用super.clone()。通过进行一次准确的复制,这样做可为后续的克隆进程建立起一个良好的基础。随后,可采取另一些必要的操作,以完成最终的克隆。

  为确切了解其他操作是什么,首先要正确理解Object.clone()为我们带来了什么。特别地,它会自动克隆所有句柄指向的目标吗?下面这个例子可完成这种形式的检测:

  //: Snake.java

  // Tests cloning to see if destination of

  // handles are also cloned.

  public class Snake implements Cloneable {

  private Snake next;

  private char c;

  // Value of i == number of segments

  Snake(int i, char x) {

  c = x;

  if(--i > 0)

  next = new Snake(i, (char)(x + 1));

  }

  void increment() {

  C++;

  if(next != null)

  next.increment();

  }

  public String toString() {

  String s = ":" + c;

  if(next != null)

  s += next.toString();

  return s;

  }

  public Object clone() {

  Object o = null;

  try {

  o = super.clone();

  } catch (CloneNotSupportedException e) {}

  return o;

  }

  public static void main(String[] args) {

  Snake s = new Snake(5, 'a');

  System.out.println("s = " + s);

  Snake s2 = (Snake)s.clone();

  System.out.println("s2 = " + s2);

  s.increment();

  System.out.println(

  "after s.increment, s2 = " + s2);

  }

  } ///:~

  一条Snake(蛇)由数段构成,每一段的类型都是Snake。所以,这是一个一段段链接起来的列表。所有段都是以循环方式创建的,每做好一段,都会使第一个构建器参数的值递减,直至最终为零。而为给每段赋予一个独一无二的标记,第二个参数(一个Char)的值在每次循环构建器调用时都会递增。

  increment()方法的作用是循环递增每个标记,使我们能看到发生的变化;而toString则循环打印出每个标记。输出如下:

  s = :a:b:c:d:e

  s2 = :a:b:c:d:e

  after s.increment, s2 = :a:c:d:e:f

  这意味着只有第一段才是由Object.clone()复制的,所以此时进行的是一种“浅层复制”。若希望复制整条蛇——即进行“深层复制”——必须在被覆盖的clone()里采取附加的操作。

  通常可在从一个能克隆的类里调用super.clone(),以确保所有基础类行动(包括Object.clone())能够进行。随着是为对象内每个句柄都明确调用一个clone();否则那些句柄会别名变成原始对象的句柄。构建器的调用也大致相同——首先构造基础类,然后是下一个衍生的构建器……以此类推,直到位于最深层的衍生构建器。区别在于clone()并不是个构建器,所以没有办法实现自动克隆。为了克隆,必须由自己明确进行。

赞(11)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程