代码即财富之我学Java对象克隆(3)

首先声明一点,虽然String也属于引用数据类型,但是它属于Java语言当中设计的特殊类型,具有值不可更改的特点,因此在进行参数传递时,不具备引用传递的特点,而是当成值传递方式来代替。

所有的对象都具有拷贝(克隆)的功能,因为Object类中就定义了clone方法。一个类需要被克隆,则该类必须明确继承Cloneable接口,该接口只是其标识作用,另外还必须在该类中重写Object类提供的clone方法,使之支持对象克隆。

Java对象一般性的克隆,属于浅克隆。浅克隆是指只克隆当前对象的副本,而不管该对象内部成员对象是否需要拷贝副本,因此成员对象还是使用原来的引用指向,所以一旦改变克隆对象的成员对象的值,原有值的成员对象属性变量的值也会发生变化。

如果需要彻底解决这种弊端,则需要一次性克隆到底,使用深克隆的方式。不但对该对象拷贝副本,对该对象成员对象也进行拷贝,甚至逐级拷贝下去,需要注意的是,这种方式下,成员对象所在类必须支持克隆属性,重写clone方法。

public class TestObjClone{
 public static void main(String[] args) {
  Person per = new Person("zhangsan", 20);
  Animal a = new Animal("xiaohei", 8, per);
  Animal b = null;
  System.out.println("before clone: ");
  System.out.println("Animal b is null and Animal a is: \n" + a);
  b = (Animal)a.clone();
  b.getMaster().setName("wangwu");
  b.getMaster().setAge(50);
  System.out.println("after clone: ");
  System.out.println("Animal b master has been changed and Animal a is: \n" + a);
 }
}
class Animal implements Cloneable{
 private String name;
 private int age;
 private Person master;
 public Animal(){
 }
 public Animal(String name, int age, Person master){
  this.name = name;
  this.age = age;
  this.master = master;
 }
 public String getName() {
     return this.name;
 }
 public int getAge() {
     return this.age;
 }
 public Person getMaster(){
  return this.master;
 }
 public void setName(String name) {
     this.name = name;
 }
 public void setAge(int age) {
     this.age = age;
 }
 public void setMaster(Person master){
  this.master = master;
 }
 public String toString(){
  return "Animal(name = " + this.getName() + ", age = " + this.getAge() 
  + ", master = \n"+ this.getMaster() +")";
 }
 public Object clone(){
  Animal obj = null;
  try{
   obj = (Animal)super.clone();
   obj.master = (Person)master.clone();
  }catch(CloneNotSupportedException e){
  }
  return obj;
 }
}
class Person implements Cloneable{
 private String name;
 private int age;
 public Person(){
 }
 public Person(String name, int age){
  this.name = name;
  this.age = age;
 }
 public String getName() {
     return this.name;
 }
 public int getAge() {
     return this.age;
 }
 public void setName(String name) {
     this.name = name;
 }
 public void setAge(int age) {
     this.age = age;
 }
 public String toString(){
  return "Per(name = " + this.getName() + ", age = " + this.getAge() + ")";
 }
 public Object clone(){
  Person obj = null;
  try{
   obj = (Person)super.clone();
  }catch(CloneNotSupportedException e){
  }
  return obj;
 }
}

输出如下:

before clone:
Animal b is null and Animal a is:
Animal(name = xiaohei, age = 8, master =
Per(name = zhangsan, age = 20))
after clone:
Animal b master has been changed and Animal a is:
Animal(name = xiaohei, age = 8, master =
Per(name = zhangsan, age = 20))

说明进行深克隆后,原有对象中成员对象属性值不会再发生改变。要想测试浅克隆只需将Person类的克隆属性去掉,即取消Cloneable接口和clone方法,另外还需注释掉Animal类clone方法里的master成员对象的克隆,即为浅克隆方式,此种方式下,原有对象的成员对象属性值也会发生改变。

转载于:https://my.oschina.net/u/1258323/blog/471695

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值