浅谈Java中的克隆机制

Posted erinchen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈Java中的克隆机制相关的知识,希望对你有一定的参考价值。

转 https://blog.csdn.net/zhaoheng314/article/details/81985880

 

Java语言中克隆针对的是类的实例

/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre/lib/rt.jar!/java/lang/Cloneable.class

根据Cloneable接口的注释, 克隆需要遵循以下规则:

  1. 必须实现Cloneable接口
  2. 实现Cloneable的类应该重写clone(),重写时该方法的修饰符为public。

  

/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre/lib/rt.jar!/java/lang/Object.class

protected native Object clone() throws CloneNotSupportedException;


age属性是int类型,基本类型克隆时只是传值,不存在传引用
String类 final关键字 不可变特性,克隆对象修改了name属性的引用


深克隆
public class Student implements Cloneable{

    private String name;//引用类型  final关键字 一是不可变,二是禁止指令重排

    private int age;//基本类型

    private Classes classes;//引用类型

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

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

    public void setClasses(Classes classes){
        this.classes = classes;
    }

    public String getName(){
        return name;
    }

    public Classes getClasses(){
        return classes;
    }

    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + ", classes=" + classes + "]";
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Student stu = (Student)super.clone();
        //克隆classes属性时候调用Classes类的clone();
        Classes cla = (Classes)classes.clone();
        stu.setClasses(cla);
        return stu;
    }
}

 

public class Classes implements Cloneable{

    private int classId;//基本类型

    private String className;//引用类型

    public void setClassId(int classId){
        this.classId = classId;
    }

    public void  setClassName(String className){
        this.className = className;
    }


    @Override
    public String toString() {
        return "Classes [classId=" + classId + ", className=" + className + "]";
    }

    @Override
    protected Object clone() throws CloneNotSupportedException{
        return super.clone();
    }
}
public class TestClone {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.setName("张三");
        stu.setAge(10);

        Classes classes = new Classes();
        classes.setClassId(101);
        classes.setClassName("一班");
        stu.setClasses(classes);


        try{
            System.out.println("深克隆测试-----");
            //克隆
            Student stu2 = (Student)stu.clone();
            System.out.println("两个对象是否相同:" + (stu == stu2));
            System.out.println("两个对象name属性是否相同:" + (stu.getName() == stu2.getName()));
            System.out.println("两个对象classes是否相同:" + (stu.getClasses() == stu2.getClasses()));
            System.out.println("深克隆,Stu" + stu);
            System.out.println("深克隆,Stu2" + stu2);

            System.out.println("修改克隆对象属性");
            stu2.setName("李四"); // public final class String 一是不可变,二是禁止指令重排 修改了name属性的引用
            stu2.setAge(20);
            stu2.getClasses().setClassId(102);
            stu2.getClasses().setClassName("二班");
            System.out.println("修改克隆对象属性后,Stu " + stu);
            System.out.println("修改克隆对象属性后,Stu2 " + stu2);

        }catch (CloneNotSupportedException e){
            e.printStackTrace();
        }



    }
}

 

以上是关于浅谈Java中的克隆机制的主要内容,如果未能解决你的问题,请参考以下文章

Java Object类中的-----------clone()克隆机制

java反射机制浅谈

浅谈浅克隆(shallow clone)和 深克隆(deep clone)

浅谈Java的反射机制

浅谈利用同步机制解决Java中的线程安全问题

GitGit 分支管理 ( 克隆远程分支 | 克隆 master 分支 git clone | 查看远程分支 git branch -a | 克隆远程分支 git checkout -b )(代码片段