关于Android的克隆模式和Java中的参数传递问题

2019-02-22  本文已影响0人  _周小二

Java中的参数传递
问:当一个对象被当作参数传递到一个方法后,
此方法可改变这个对象的属性,
并可返回变化后的结果,
那么这里到底是值传递还是引用传递?
答: 是值传递。 Java 编程语言只有 值传递参数。所以是值传递.

问 : 传递一个对象和传递一个原始类型有什么不同?
答 : 当一个对象实例作为一个参数被传递到方法中时,参数的值 就是 该对象的引用一个副本。
指向同一个对象,对象的内容可以在被调用的方法中改变,
但对象的引用(不是引用的副本)是永远不会改变的。

Java参数,不管是原始类型还是引用类型,
传递的都是副本(有另外一种说法是传值,但是说传副本更好理解吧,传值通常是相对传址而言)。

如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,
这个跟之 前所谈的传值是一样的。如果在函数中改变了副本的值不会改变原始的值.
  
如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址
如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,
那么在函数内的改变会影响到传入的参数。
如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,
此时传入的参数还是指向原来的 地址,所以不会改变参数的值。

简单来说 如果参数是一个类那么值传递 传的值就是引用参数的副本 这个副本存放的是参数地址
如果是基础类型那个这个副本就是原始的参数

那么Android的克隆模式

public class Teacher implements Cloneable {
    public String name;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

public class Student implements Cloneable {
    public String name;
    public String ID;
    public int age;

    public Teacher teacher;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

private void text() {
        Student student = new Student();
        student.name = "65654";
        student.age = 20;
        student.ID = "9494";
        student.teacher= new Teacher();
        student.teacher.name = "kkk";
        Student student1 = null;
        try {
            student1 = (Student) student.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        student1.name = "55555";
        student1.ID = "100";
        try {
            student1.teacher = (Teacher) student.teacher.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        student1.teacher.name = "8704";
        setStudent(student1);
        student1.name = "text123";
    }

    private void setStudent (Student student) {
        student.ID = "setStudent";
    }


上面用的是深克隆模式 就是Student里面的Teacher类在复制的时候也是用了克隆模式的
反之浅克隆就是Teacher不用克隆模式就ok了
用的克隆模式的参数在内存中指向的地址是不一样的 所以克隆出来的类和之前的类除去名字一样其他事没有任何关系的
深克隆的log:


图片.png

浅克隆的log


图片.png

可以看到浅克隆的teacher地址是一样的 是没有被克隆的

上一篇下一篇

猜你喜欢

热点阅读