值传递与地址传递(从栈和堆的角度分析)

看前须知:

1.基本数据类型的数据存储在栈中;
2.除基本数据类型外的数据类型(就是引用类型)的数据存储在堆中,引用类型的数据都会分配一个地址储存在栈中。
3.用System.out.println();语句输出的数据是栈中存储的数据。

值传递

基本数据类型

例1

int a = 10;//int 是基本数据类型
System.out.println(a);

结果

10

int是基本数据类型,当a被赋值10时,10被存入了栈中。输出时输出栈中的内容,也就是10.

例2

int a=10;
int b = a;
System.out.println(b);

结果

10

给a赋值时,10存入了栈中,将a的值传递给b时,其实是将a的值复制一下粘贴到b在栈中的存储空间中了,并没有改变a的值。

图解:

引用数据类型

例3

int ages [] = {10,11,12};//数组是引用类型。
System.out.println(ages);

结果

[I@52e922

数组的数据存储在堆中,栈中储存的是数据的地址,所以例3输出的结果是地址。
图解
10,11,12都是以二进制补码的形式存储的,我这样写是看着方便。

public static void main(String[] args) {
        int c =100;//100先存入c的栈中;
        test(c);//跳转到函数test
       System.out.println(c); //输出c的栈中的那个没有改变的数值100;
    }
    public static void test(int d) {    //d引用了c的栈中的数值100复制到自己的栈中;
    	System.out.println(d); //输出栈中的内容
    	d=0; //将d的栈中的100改为0;不形象c的栈中的那个数值100;
    }

结果

100
100

总结

赋值其实是将栈中的数据复制粘贴。输出时也只输出栈中的数据。基本数据类型只在栈中搞事情,堆中不开辟空间。

地址传递

例4

int c []= {100,200};
int d []= new int [2];
d=c;
System.out.println(d);
System.out.println(d[0]);

结果

[I@52e922
100

100和200存入了堆中。这是把数组c的栈中的地址复制到了数组d的栈中,使数组c和d指向同一个堆。
图解
在这里插入图片描述
100和200存入了堆中。这是把数组c的栈中的地址复制到了数组d的栈中,使数组c和d指向同一个堆。
例5

public static void main(String[] args) {
        int c []= {100,200};
        System.out.println(c[0]);//输出:100
        test(c);
        System.out.println(c[0]);  //输出:0
    }
    public static void test(int array [] ) {
    	System.out.println(array);输出:数组a的‘地址’
    	array[0]=0;
    }

结果

100
[I@52e922
0

由上边结果看来:test引用数组c时,是将数组c的地址传递了过来,array[0]=0;改变的是数组a传递过来的地址所指的堆中的数据。

图解

地址传递后数组c和数组array的地址相同,都指向堆中的同一个内存空间,所以array[0]=0;改变了堆中的数据,影响了数组c的值。

ps:以上为值传递和地址传递的一种理解方式,由于作者暂时知识有限,仍有欠缺,也是些许遗憾。以后会不定期补充内容并拓展其他理解方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值