Clone in java

Cloning
A class object with an assignment method is called a mutable object, and a class object without an assignment method is called an immutable object.

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

There is no declaration method in the interface Cloneable, it is only used to indicate that a class implements 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 + '\'' +
                '}';
    }
}

How to copy? ? ? Shallow copy and deep copy
When the data field is an object, there are two methods.
(1) You can copy the reference to the object, and clone the shared object, shallow copy
(2) Copy the object itself, called deep copy

The clone() method of Object returns a shallow clone. The class Name has data members first and last. It is an instance of String. A reference to a character in each field. It is these references that are not copied when the clone method in Name is called. . .

For the Name class, shallow cloning is sufficient, because String instances are immutable. So let the instance of Name and it share the same string will not be a problem, because the string cannot be changed. . .

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);
    }
}

! ! ! When a class has mutable objects as data fields, shallow cloning is not appropriate, and you cannot simply copy their references when cloning objects.

Now the instance of Name is used as a member of the class Student. Because Name has a set method, deep cloning is required.

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 + '\'' +
                '}';
    }
}

Summary; in each public clone() method, the following tasks are generally performed:
1. Write super.clone() to call the clone method of the super class
2. Put the call in the try block, and write a catch block to handle possible The exception CloneNotSupportedException
can be skipped if a public clone() method is called.
3. If possible, clone the variable data of the object returned by super.clone() and
4. Return the clone

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 = ""
    }
}

Guess you like

Origin blog.csdn.net/weixin_45773632/article/details/109536684