**Java中值传递(值拷贝)和地址传递(地址拷贝)问题

首先说结论:

  1. 值传递:基本数据类型。
  2. 地址传递:引用数据类型。

Java中的数据总体来说可以分为两类:基本数据类型和引用数据类型。基本数据类型比如:int、long、float等四类八种。引用数据类型如:数组、字符串、对象等。而我们Java的jvm模型大概由三块内存结构组成。分为栈、堆、方法区。当然这些结构可以划分的更细,此处基于这三者完全可以将今天的问题阐述清楚,因而不做过多描述。基本数据类型存储在栈空间当中,传递也是在栈中进行操作,数据是存储在栈中。而引用数据的创建需要在堆中开辟一块新的空间,用于存储数据,生成对应的地址,栈中的变量指向这个堆中的地址,进而拿到数据,数据是存储在堆中。如下代码所示:

public static void main(String[] args) {
       int n1 = 10;
       int n2 = n1;
       n2 = 80;
        System.out.println("n1:"+n1);//n1:10
        System.out.println("n2:"+n2);//n2:80
        int [] arr1 = {10,20,30};
        int [] arr2 = arr1;
        arr2[0] = 10;
        for (int i = 0; i <arr1.length ; i++) {
            System.out.println("arr1:"+arr1[i]);
        }
        for (int i = 0; i <arr2.length ; i++) {
            System.out.println("arr2:"+arr2[i]);
        }
    }

输出结果:

n1:10
n2:80
arr1:10
arr1:2
arr1:3
arr2:10
arr2:2
arr2:3

对,你没看错,数组arr2的值改变影响到了arr1数组的值。神奇不?惊讶不?是不是要怀疑人生了哈哈!莫急,稳住!!听小弟娓娓道来。为了说明其中缘由,结合以下结构图进行分析。

java快递地址分割_开发语言


1.基本数据类型:

int n1 = 10; // 在栈中创建了一个变量 n1,并初始化为10,此时数值10是直接存储在栈中的。

int n2 = n1;// n2指向n1,本质就是在栈中将n1的值10复制一份给n2。

n2 = 80;// 将n2的值由10变成80。注意:此时n1的值仍然是10,因为它只是复制(拷贝)了一份数据10给n2,并没有对自己产生任何影响和改变。因而说,基本数据类型的本质是值传递,或者说值拷贝。

2.引用数据类型:

int [] arr1 = {10,20,30};// 在栈中创建了一个变量arr1,并初始化为1,2,3。注意:此时1,2,3这三个数值并不是直接存储在栈中的,而是在堆中开辟了一块空间来进行存储,同时会生成对应的类似于十六进制的地址0x0011,栈中的变量arr1指向这个地址。

int [] arr2 = arr1; // arr2指向arr1,本质就是将arr1的地址0x0011复制一份给arr2。(切记:不是把1,2,3直接给arr2)。

arr [0] = 10; // 将arr2的值由1变成10。注意:此时arr1的值也会变成10,因为上面是将arr1的地址0x0011复制(拷贝)一份给arr2,并不是直接把值复制(拷贝)给arr2,所以它们共同指向了同一个地址,相当于一扇门有两把钥匙,这两把钥匙都可以打开这扇门。因而说,引用数据类型的本质是地址传递,或者说是地址拷贝。

好了,说到这里,Java中值传递还是地址传递的问题应该是比较清楚了。如果小伙伴们还有什么疑惑的地方,欢迎大家留言评论,我们一起相互学习讨论。