美文网首页
Android - 值传递还是引用传递???

Android - 值传递还是引用传递???

作者: xlq | 来源:发表于2020-04-28 20:40 被阅读0次

    本篇文章记录一些本人关于值传递或引用传递的理解,补一补大学的基础,老泪纵横。有疑问还请怒怼。

    1. 首先说一下关于对象的创建

    Person me = new Person("Franklin") , 这句代码包含几个步骤:

    1. new Person :代表在堆内存中为实际对象开辟空间;
    2. ("Franklin") :代表给对象初始化;
    3. Person me : 代表对象在堆中的地址,也可以叫引用,保存在栈内存中;
    4. = : 代表将实际对象在堆中的内存地址赋值给了me

    2. 弄清楚基本类型和引用类型

    int a = 100; a是基本类型
    String s = "sss"; s是引用类型

    Java的8大数据类型,都属于基本类型。
    对象都属于引用类型。

    3. 弄清楚实参和行参

    方法声明:

    public void fun(int age , String name) {} // age 和 name 是行参
    

    方法调用:

    fun(25,"Franklin");  // 25 和 "Franklin"是实参
    

    行参只在该方法被执行的时候,才会开辟内存。方法运行结束之后,行参会被销毁,内存被回收。

    4. Java中的方法调用都是值传递

    具体原因在这里很难说清楚,其实也不需要在这里纠结。我们只需要知道方法调用时,行参和实参的执行原理就行了。掌握了原理,以后自己写代码或者“去造火箭”都是可以轻松拿下的。

    5. 示例
    public class Person {
        private int age;
        private String name;
    
        public Person(int age, String name) {
            this.age = age;
            this.name = name;
        }
    
        public void setInformation(int age, String name) {
            this.age = age;
            this.name = name;
        }
    }
    

    先预告一笔,setInformation方法很重要。

    private static void changeInfo (Person p1, Person p2) {
        Person tempPerson = p1;
        p1 = p2;
        p2 = tempPerson;
        p1.setInformation(50,"王五");
        p2 = new Person(60,"赵六");
    }
    
    public static void main(String[] args) {
        Person p1 = new Person(30,"张三");
        Person p2 = new Person(40,"李四");
        changeInfo(p1, p2);
        Log.d("Franklin", p1.name + "," + p1.age + "\n" + p2.name + "," + p2.age)
    }
    

    不要往下拉,你觉得应该打印什么呢?

    一步步分析:

    1. 先创建p1 和 p2两个对象的引用,他俩分别指向堆内存中的张三和李四;

    2. changeInfo(p1,p2)将引用传入方法。请注意:在java中给方法传引用都是传的引用的copy。 意思就是现在栈内存中有p1和p1' 两个引用指向了张三,有p2和p2' 两个引用指向李四;

    3. 在changeInfo方法中的前三行代码,很明显是一个交换值的操作,即p1'和p2' 所指向的对象交换。所以目前是 p1和 p2' 指向张三,p2和p1' 指向李四;

    4. 继续 p1.setInfomation(50,"王五"),这句很强势。它代表:使用对象自己的可以改变自身属性的方法来改变自己。这句话应该好懂吧!还是举几个例子: List的add方法 、 StringBuilder的append方法。 这句话执行之后,p1' 所指向的李四就隐姓埋名了,改成了50岁的王五。多说一句:此时内存中p2指向不受影响,还是指王五,也就是之前的李四;

    5. 最后p2 = new Point(80,"赵六") 这句代码和我们刚开始第一节对象的创建一样啊。所以这时候 p2' 就不指向张三啦,p2' 指向的是系统在堆中重新创建的一个赵六的对象。

    6. 分析完了最后再总结一下,此时栈和堆之间的指向关系:
      p1 -> 张三
      p2 -> 王五
      p1' -> 王五
      p2' -> 赵六
      而changeInfo方法走完之后,copy出来的临时指针p1'和p2' 会被销毁,内存回收。堆中没有被指针指的赵六,就被视为垃圾,也会被回收。

    7. 最终日志打印出来就是
      张三,30
      王五,50

    看到这,是不是有种恍然大明白的感觉???

    总结一句话:
    如果对象没有改变自己的方法,通过行参无法改变对象。

    相关文章

      网友评论

          本文标题:Android - 值传递还是引用传递???

          本文链接:https://www.haomeiwen.com/subject/ufpbwhtx.html