值传递与地址传递
值传递和地址传递
如果是数组类的引用类型,是在堆中存储数组里的数,然后将这些数的首地址赋值到栈中,最后输出的是栈中的首地址;如果是基本数据类型,直接将数值的二进制补码存到栈中,输出的就是栈中的具体数值。
eg1:运行如下程序
在电脑运行不同程序时,会在内存条里开辟不同的运行区。如图:
而在Java内存区里,会有堆和栈两个作用区,栈的特点是先进后出,堆的特点是先出后进。
首先在执行代码int ages [ ] = { 12,17,21}时,因为数组是引用类型,因此在内存条的栈里会开辟一个ages的空间,然后在堆里开辟一个空间,分成3个小空间存代码里3个int类型的值,因为是int类型,所以是32位的二进制补码。然后在执行等号赋值时,会将堆里的首地址给栈里的ages空间,因此,在输出ages时,输出的是栈中的数组的首地址。
在执行int score = 100 时,由于int是基本数据类型,因此会直接在栈里开辟一个score空间,将100的32位二进制补码直接存在这个空间。因此,在输出score时,输出的栈中的数100。
eg2:运行如下程序
代码int [ ] scores ={100};仍然是数组类型,因此输出scores仍旧是首地址,具体如eg1。
运行test (scores) 时,由于public static void test ( int [ ] array ),因此先在栈里再开辟一个新空间array,由于是后进的,因此在空间scores上面,然后将scores里的地址53e922复制到array空间里,因此输出array仍然是输出同样的首地址。
然后运行代码array [ 0 ] = 0;将堆里储存的数据由100 变成0,因此最后输出的scores数值是0而不是100。
eg3:运行如下程序
由于只是基本类型,因此只用到栈作用区,而a = 0 即在栈中将a的值从100改成0。因此输出score和没有改成0之前的a都是100。