Day18:值传递和引用传递的内存分析

值传递和引用传递

首先我们先回忆一下数据类型:

Java中数据类型分为基本类型和引用类型,其中引用类型涉及到对象的建立。

从内存角度分析的话,基本类型存放在栈内存中,而对象则是存放在堆内存中。

  • 值传递

public class Demo{
    public static void main(String[] args){
        int a=1;
        System.out.println("调用方法前的值:"+a);
        change(b);
        System.out.println("调用方法后的值:"+a)
    }
    public static void change(int b){
        b=10;
    }
}
//运行结果
调用方法前的值:1
调用方法后的值:1

我们发现在方法执行后运行结果都是一致的。

但按常理来说,我们的数据在经过方法的改变后,值会发生变化。

这里涉及到Java在方法执行时根据参数类型不同而产生的不同的传递方式。

让我们从内存的角度出发来进行分析

  • 引用传递

public class Demo{
    public static void main(String[] args){
        Dog A=new Dog();//类实例化
        System.out.println("改变前A的名字:"A.name);
        change(A);//调用方法
        System.out.println("改变后A的名字:"A.name);
    }
    public static void change(Dog a){
        a.name="工地佬"
    }
}
class Dog{//我们创建一个狗类
    String name;//加上一个名字属性,但不予以赋值
}
//输出结果
改变之后前的名字:null
改变之后的名字:工地佬

我们发现经过change方法的执行,Dog的名字从null变化为了工地佬,为什么这一次的方法改变了我原有的值呢?

对比上面的值传递的数据类型,我们发现,我们这次传参的数据类型为引用类型,我们是将一个对象作为了参数;

从内存的角度分析:

对象是存放在堆内存中,方法和变量名是存放在栈中。

当我们创建一个对象A时,在栈内存里面就存放了一个变量名A,在堆内存中即开辟了一个新内存来存放对象的属性,每个内存在堆中都有自己的地址,而A则含有属于它的对象的地址;当我们把对象A作为参数在方法运行时,A把地址给了方法,方法则根据地址来到堆内存对对象执行方法,如果对象被改变,则A也发生变化。

再举一个不恰当的例子:

值传递:甲有10元钱,乙知道后,把自己的10元钱换了两张5元的;乙换完之后并不会对甲的钱有什么影响;两者完全互不相干

引用传递:甲有10元钱,乙知道甲存钱的地址之后,把钱换成了两张5元的;乙换完之后甲的钱从10元变成了2张五元的;甲被影响到了,他的钱变了

posted @ 2022-11-21 10:18  工地佬  阅读(54)  评论(0)    收藏  举报