Cloneable测试

一.Cloneable 的用途 
  Cloneable和Serializable一样都是标记型接口,它们内部都没有方法和属性,implements Cloneable表示该对象能被克隆,能使用Object.clone()方法。如果没有implements Cloneable的类调用Object.clone()方法就会抛出CloneNotSupportedException。 

二.克隆的分类 
  (1)浅克隆(shallow clone),浅拷贝是指拷贝对象时仅仅拷贝对象本身和对象中的基本变量,而不拷贝对象包含的引用指向的对象。 
  (2)深克隆(deep clone),深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。 

举例区别一下:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2,A2中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2中包含对C2(C1的copy)的引用。 

三.克隆的举例 
  要让一个对象进行克隆,其实就是两个步骤: 
  1. 让该类实现java.lang.Cloneable接口; 
  2. 重写(override)Object类的clone()方法。

Demo:

1.浅克隆

public class Animal implements Cloneable{

    private int age;
    private String name;
    
    public Object clone() throws CloneNotSupportedException{
        return super.clone();
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    
}

测试类:

public class TestMain {
    public static void main(String[] args) throws Exception {
        Animal animal1 = new Animal();
        animal1.setAge(12);
        animal1.setName("狮子");
        
        Animal animal2 = (Animal) animal1.clone();
        //animal2.setName("老虎");
        
        System.out.println("类型比较:"+(animal1==animal2));
        System.out.println("基本数据类型比较:"+(animal1.getAge()==animal2.getAge()));
        System.out.println("引用数据类型地址比较:"+(animal1.getName()==animal2.getName()));
        System.out.println("引用数据类型内容比较:"+(animal1.getName().equals(animal2.getName())));
        System.out.println("引用数据类型内容:"+animal1.getName()+"/"+animal2.getName());
    }
    
}

输出结果:

类型比较:false
基本数据类型比较:true
引用数据类型地址比较:true
引用数据类型内容比较:true
引用数据类型内容:狮子/狮子

 

2.深克隆

public class Animal implements Cloneable{

    private int age;
    private String name;
    
    public Object clone() throws CloneNotSupportedException{
        Animal animal = (Animal) super.clone();
        animal.name = new String(this.name);
        return animal;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
}

测试类:

public class TestMain {
    public static void main(String[] args) throws Exception {
        Animal animal1 = new Animal();
        animal1.setAge(12);
        animal1.setName("狮子");
        
        Animal animal2 = (Animal) animal1.clone();
        //animal2.setName("老虎");
        
        System.out.println("类型比较:"+(animal1==animal2));
        System.out.println("基本数据类型比较:"+(animal1.getAge()==animal2.getAge()));
        System.out.println("引用数据类型地址比较:"+(animal1.getName()==animal2.getName()));
        System.out.println("引用数据类型内容比较:"+(animal1.getName().equals(animal2.getName())));
        System.out.println("引用数据类型内容:"+animal1.getName()+"/"+animal2.getName());
    }
    
}

测试结果:

类型比较:false
基本数据类型比较:true
引用数据类型地址比较:false
引用数据类型内容比较:true
引用数据类型内容:狮子/狮子

 

总结:浅克隆是把该对象的基本数据及引用地址复制,深克隆是把该对象的基本数据以及对象copy到另一个地址

posted @ 2018-01-11 16:06  取什么昵称呢  阅读(199)  评论(0编辑  收藏  举报