java之克隆clone解密

为了理解java的clone,有必要先温习以下的知识。

  java的类型,java的类型分为两大类,一类为primitive,如int,另一类为引用类型,如String,Object等等。

  java引用类型的存储,java的引用类型都是存储在堆上的。

  Java代码

  public class B {

  int a;

  String b;

  public B(int a, String b) {

  super();

  this.a = a;

  this.b = b;

  }

  }

  对这样一个引用类型的实例,我们可以推测,在堆上它的内存存储形式(除去指向class的引用,锁的管理等等内务事务所占内存),应该有一个int值表示a,以及一个引用,该引用指向b在堆上的存储空间。

  为什么要clone

  恩,因为需要。废话。

  有名的GoF设计模式里有一个模式为原型模式,用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.

  简单的说就是clone一个对象实例。使得clone出来的copy和原有的对象一模一样。

  插一个简单使用clone的例子,如果一个对象内部有可变对象实例的话,public API不应该直接返回该对象的引用,以防调用方的code改变该对象的内部状态。这个时候可以返回该对象的clone。

  问题来了,什么叫一模一样。

  一般来说,有

  x.clone() != x

  x.clone().getClass() == x.getClass()

  x.clone().equals(x)

  但是这些都不是强制的。

  我们需要什么样的clone就搞出什么样的clone好了。

  一般而言,我们要的clone应该是这样的。copy和原型的内容一样,但是又是彼此隔离的。即在clone之后,改变其中一个不影响另外一个。

  Object的clone以及为什么如此实现

  Object的clone的行为是最简单的。以堆上的内存存储解释的话(不计内务内存),对一个对象a的clone就是在堆上分配一个和a在堆上所占存储空间一样大的一块地方,然后把a的堆上内存的内容复制到这个新分配的内存空间上。

  看例子。

  Java代码

  class User {

  String name;

  int age;

  }

  class Account implements Cloneable {

  User user;

  long balance;

  @Override

  public Object clone() throws CloneNotSupportedException {

  return super.clone();

  }

  }

  Java代码

  // user.

  User user = new User();

  user.name = "user";

  user.age = 20;

  // account.

  Account account = new Account();

  account.user = user;

  account.balance = 10000;

  // copy.

  Account copy = (Account) account.clone();

  // balance因为是primitive,所以copy和原型是相等且独立的。

  Assert.assertEquals(copy.balance, account.balance);

  copy.balance = 20000;

  // 改变copy不影响原型。

  Assert.assertTrue(copy.balance != account.balance);

  // user因为是引用类型,所以copy和原型的引用是同一的。

  Assert.assertTrue(copy.user == account.user);

  copy.user.name = "newName";

  // 改变的是同一个东西。

  Assert.assertEquals("newName", account.user.name);

  恩,默认实现是帮了我们一些忙,但是不是全部。

  primitive的确做到了相等且隔离。

  引用类型仅仅是复制了一下引用,copy和原型引用的东西是一样的。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/11134734/viewspace-631842/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/11134734/viewspace-631842/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值