java中克隆

克隆
有赋值方法的类对象称为可变对象,没有赋值方法的类对象称为不可变对象。

//因为Object是所有其他类的超类,所以任意方法的实现中都可以含有调用,但是类的客户不能调用clone()
//除非类重写了且将它声明为公有的。对对象进行复制可能很费时间。。。
protected Object clone() throws CloneNotSupportedException;

接口Cloneable中没有声明方法,只专门用来表示一个类实现了clone().

public interface Cloneable(){
        
        }
        //空的Cloneable接口不是一个典型的接口,实现它的类表示,它提供了一个公有的clone方法。因为java提供了clone()方法的默认实现,故将它放在Object类中,没有放在Cloneable接口中。但因为不想让每一个类都自动拥有一个公有的clone()方法,所以clone()方法是一个保护方法。
public class Name implements Cloneable{
    private String first;
    private String last;
    
    public Object clone(){
        Name theCopy = null;
        try {
            theCopy = (Name)super.clone();//必须调用超类的方法
        }catch (CloneNotSupportedException e){
            throw new Error(e.toString());//System.err.println("Name cannot clone: "+e.toString());
            
        }
        return theCopy;//隐式转换
    }

    public Name(){

    }

    public Name(String firstName,String lastName){
        first = firstName;
        last = lastName;
    }

    public void setName(String firstName,String lastName){
        setFirst(firstName);
        setLast(lastName);
    }

    public String getName(){
        return toString();
    }

    
    public void setFirst(String firstName){
        first = firstName;
    }

    public String getFirst(){
        return first;
    }

    public void setLast(String lastName){
        last = lastName;
    }

    public String getLast(){
        return last;
    }

    public void giveLastNameTo(Name aName){
        aName.setLast(last);
    }

    @Override
    public String toString() {
        return "Name{" +
                "first='" + first + '\'' +
                ", last='" + last + '\'' +
                '}';
    }
}

怎么复制??? 浅复制和深复制
当数据域是一个对象时,有两种方法。
(1)可以复制指向对象的引用,并于克隆共享对象,浅复制
(2)复制对象本身,称为深复制

Object的clone()方法返回一个浅克隆。类Name有数据成员first和last。它是String的实例。每个域中旱藕一个指向字符的引用。当调用Name中的clone方法时没复制的正是这些引用。。。

对于该Name类来说,浅克隆已经够用了,因为String实例是不可变的。所以让Name的实例和其共享相同的字符串不会有问题,因为不能改变字符串。。。

class test{
    public static void main(String[] args) {
        Name a = new Name("haixia","zhang");
        Name b = (Name)a.clone();//b是a的浅克隆
        System.out.println(a+" "+b);

        b.setLast("lu");
        System.out.println(a+" "+b);
    }
}

!!!当一个类有可变对象作为数据域时,浅克隆时不合适的,克隆对象时不能简单地复制他们的引用。

现将Name的实例作为类Student的成员,因为Name有set方法,所以,需要采用深克隆。

public class Student implements Cloneable{
    private Name fullname;
    private String id;

    public Object clone(){
        Student theCopy = null;
        try {
            theCopy = (Student)super.clone();
        }catch (CloneNotSupportedException e){
            throw new Error(e.toString());
        }

        theCopy.fullname = (Name)fullname.clone();
        return theCopy;
    }
    public Student(){
        fullname = new Name();
        id = "";
    }
    public Student(Name studentName,String studentId){
        fullname = studentName;
        id = studentId;
    }
    public void setStudent(Name studentName,String studentId){
        setName(studentName);
        setId(studentId);
    }
    public void setName(Name studentName){fullname = studentName;}
    public Name getName(){return fullname;}
    public void setId(String studentId){id = studentId;}
    public String getId(){return id;}

    @Override
    public String toString() {
        return "Student{" +
                "fullname=" + fullname +
                ", id='" + id + '\'' +
                '}';
    }
}

总结;在每一个公有clone()方法内,一般执行下列任务
1.写super.clone()调用超类的clone方法
2.将对这个调用含在try块中,且写一个catch块处理可能的异常CloneNotSupportedException
如果调用的是一个公有的clone()方法则可以跳过。
3.可能的话,克隆super.clone()返回的对象的可变数据与
4.返回克隆

public class CollegeStudent extends Student{
    private int year;
    private String degree;

    public Object clone(){
        //因为CollegeStudent对象的数据域是基本类型值和不可变数据对象,故它们不需要被克隆。
        CollegeStudent theCopy = (CollegeStudent)super.clone();
        return theCopy;
    }

    @Override
    public String toString() {
        return super.toString() + ", " + degree + ", " + year;
    }

    public CollegeStudent(){
        super();
        year = 0;
        degree = ""
    }
}

posted @ 2020-11-08 15:18  木有呂朋友  阅读(35)  评论(0)    收藏  举报