参数传递
方法调用的时候,涉及到参数传递的问题,传递的时候,Java只遵循一种语法机制,就是将变量中保存的"值"传递过去了。只不过有的时候这个值是一个字面值,有的时候这个值是另一个Java对象的内存地址。
基本数据类型和String类型传递的是字面值,而引用数据类型(String类型除外)传递的是地址。所以对如引用数据类型(除String)来说,只要方法中形参对(在和实参指向的地址一样的情况下)其内容进行改变,调用方法后,实参的内容就会改变。而基本数据类型和String,无能怎么修改其内容都不会影响实参的内容。所以不管对于引用数据类型(当形参指向地址和实参不一样的时候)还是基本数据类型来说要想得到方法调用后的值,都必须通过return来获得,并用在main方法中用一个变量来接收。因为形参和实参会开辟两个不同的内存空间,只是在进行传递的时候可能引用数据量将实参指向的地址传给了形参,这个时候用形参修改内容,就是修改堆内存中的内容(实参所指向的内容),当形参指向的地址和实参不一样的时候是无法改变实参的内容的。
例如:动态数组。
public class Test02 {
public static void main(String[] args) {
//创建一个数组
int[] array = {1, 2, 3, 4, 5, 6};
//输出原始数组的内容
System.out.println("调用之前的数组:" + Arrays.toString(array));
//将原始数组的地址改为方法调用后的数组,将临时数组的地址覆盖原始数组的地址
array = getTempArray(array, 7, 6);
//输出修改后的数组
System.out.println("调用之后的数组:" + Arrays.toString(array));
}
//在数组中指定位置插入一个数
public static int[] getTempArray(int[] arr, int num, int index) {
//由于数组一旦创建就无法改变其长度和内容,所以只能创建一个临时数组来接收
//原始数组的内容加上添加或者减少或修改的部份。
int[] temparray = new int[arr.length + 1];
for (int i = 0; i < temparray.length; i++) {
if (i < index)
temparray[i] = arr[i];
else if (i == index)
temparray[i] = num;
else
temparray[i] = arr[i - 1];
}
arr = temparray;//这里可以不要arr=temparray;在return里面直接写return temparray;就可以
return arr;//保存局部变量temparray的内容,防止被回收
}
}
结果:
程序运行图解
之前一直在纠结如果不返回array,temparray被回收,形参arr指向的不就是空吗?为啥主方法中的实参输出结果还是原始数组,不用应该为空吗?画图画出后会觉得很傻,这是啥问题。方法执行完后实参跟形参有关联吗?没有。实参和形参在不同方法中,实参和形参的内存空间不一样,实参内存空间是实参的,形参内存空间是形参的,main方法中输出的结果是实参所指向的结果,跟形参无关。不要弄混淆对内容修改的就会修改实参内容。那是因为形参和实参指向的都是同一个地址时候,对内容进行修改,调用方法之后,原始数组不就会改变么,输出实参内容(就是原始数组内容)不就变了么。如下:
public class Test03 {
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6};
System.out.println("调用之前:"+Arrays.toString(array));
setArray(array);
System.out.println("调用之后:"+Arrays.toString(array));
}
public static void setArray(int[] arr) {
arr[0] = 0;
}
}
调用方法后,实参的内容发生改变,不用return 和改变引用指向就变了。
基本数据类型和String
public class Test04 {
public static void main(String[] args) {
int a = 1;
String s = "LH";
System.out.println("a-----" + a);
System.out.println("s-----" + s);
add(a);
change1(s);
System.out.println("a-----" + a);
System.out.println("s-----" + s);
a = add2(a);
s = change2(s);
System.out.println("a-----" + a);
System.out.println("s-----" + s);
}
public static void add(int a) {
a++;
}
public static int add2(int a) {
a++;
return a;
}
public static void change1(String s) {
s = "HH";
}
public static String change2(String s) {
s = "HH";
return s;
}
}
你会发现方法调用后,值还是没有改变,只要在reurn和重新接收后才改变了。
针对此类问题,如果实在想不出来,画图即可,一目了然。