public static void main(String[] args) {
//创建一个初始的参数
int[] arr =new int[] {1,2,3};
newAdd(arr);
//输出
System.out.println(Arrays.toString(arr));
}
//创建一个方法改变参数的地址指向
public static void newAdd(int[] arr) {
int[] arr2 = new int[] {1,2,3,0};
arr=arr2;
}
运行结果是:{1,2,3}
可以看到在方法newAdd中有一个传地址的操作,但是他的运行的结果并不是{1,2,3,0}
这一个问题是在我们刚开始接触编程的时候很容易搞混淆的一个案例。
如下图所示,将数组指向的地址用图像来表示:
这是未进行传地址之前的一个地址的指向,因为是引用数据类型,所以两个arr指向的是同一个地址,但这两个arr在栈内存中的位置并不是同一个。
int[] arr2 = new int[] {1,2,3,0};
arr=arr2;
在执行传地址操作之后可以看到newAdd中的arr和arr2指向了同一个地址但是这并没有影响main中的arr的指向,在main函数中输出的arr指向是没有变的,所以输出的结果是{1,2,3}并不是{1,2,3,0}。
可以将代码修改为:
public static void main(String[] args) {
//创建一个初始的参数
int[] arr =new int[] {1,2,3};
arr=newAdd(arr);
//输出
System.out.println(Arrays.toString(arr));
}
//创建一个方法改变参数的地址指向
public static int[] newAdd(int[] arr) {
int[] arr2 = new int[] {1,2,3,0};
arr=arr2;
return arr;
}
将方法中修改过后newAdd中的arr的地址返回给main中的arr,这样就改变了main中的arr的地址,而未被指向的地址会被当成垃圾回收,最后我们输出的结果就会变成:{1,2,3,0}
那问题又来了如果我改变代码为:
public static void main(String[] args) {
//创建一个初始的参数
int[] arr =new int[] {1,2,3};
newAdd(arr);
//输出
System.out.println(Arrays.toString(arr));
}
//创建一个方法改变参数的地址指向
public static void newAdd(int[] arr) {
arr[0]=10;
}
这里我修改了代码在方法体中改变了参数数组的值,那么在main函数中输出的值应该是多少?
运行程序之后得到的结果是:{10,2,3}。这个问题的关键的地方容易和上一个案例搞混,画图如下:
这是未执行方法体之前数组地址指向的示意图,因为是引用数据类型,所以两个arr指向的是同一个地址,当执行方法体修改了newAdd中arr的值时:
arr[0]=10;
在执行方法体之后,可以看到main函数中arr所指向的值也是发生了变化,所以在main函数中在输出arr的值也是修改过后的值,结果为:{10,2,3}。
总结一下就是,在给方法传递参数是引用类型时:如果在方法体中修改了形参的地址,且无返回值时,对实参没有任何的影响,但返回值被实参接收时,实参也会发生改变;如果修改的是形参的值,且未修改形参的地址,则无论有无返回值,实参都是会变化的。