Java中方法调用时参数的传递方式都是值传递。细分为以下两种情况:
1. 当参数为基本类型(int、long、double...)或String类型(必须是String s ="xxx";方式声明的)时,传递的是该变量的值;
2. 当参数为引用类型(除了1中说明的String那种情况)时,传递的是该变量引用的地址的值。
Object obj = new Object();
以上代码做了两件事(见下图):
1. 声明了一个变量obj,保存在栈中;
保存在栈中的变量的数据结构,可简单理解为下图:
变量名称 | 本身的值或者引用地址的值 |
2. 创建了一个Object对象,保存在堆中。
保存在堆中的值的数据结构,可简单理解为下图:
地址 | 对象的值 |
例:
public class Test {
public static voidargs) {
// 1
inti=0;
modifyInt(i);
System.out.println(i);
// 2
s1"a";
modifyStr(s1);
System.out.println(s1);
// 3
s2 = new"a");
modifyStr(s2);
System.out.println(s2);
// 4
arr1"a", "b"};
modifyArr(arr1);
System.out.println(arr1[0]+","+arr1[1]);
// 5
arr2"a", "b"};
modifyArr2(arr2);
System.out.println(arr2[0]+","+arr2[1]);
}
public static void modifyInt(intt){t=1;}
public static voidt){t"c";}
public static voidt){t = new"c");}
public static voidt){t[0]="c";}
public static voidt){t = new"c"};}
}
1. i变量在栈中如下
i | 0 |
当传给 modifyInt(t)时,新增了一个局部变量t,并将i=0的值传递给t,此时栈中变量如下:
i | 0 |
t | 0 |
所以在modifyInt(t)中的修改,实际上修改的是t的值,执行modifyInt(t)后,如下:
i | 0 |
t | 1 |
2. 同1
3. s2变量在栈中如下
s2 | 0001(引用的堆中的首地址) |
堆中 0001地址处的值,如下:
0001 | "a" |
当传给 modifyStr2(t)时,新增了一个局部变量t,并将s2=0001的值传递给t,此时栈中变量如下:
s2 | 0001 |
t | 0001 |
在modifyStr2(t)中的执行t=new"c")时,先在堆中创建了新的对象"c",如下:
0001 | "a" |
0002 | "c" |
然后,将t的引用指向新的值:
t | 0002 |
所以,s2的值并没有变,执行modifyStr2(t)后,如下:
s2 | 0001 |
t | 0002 |
4. arr1变量在栈中如下
arr1 | 0003(引用的堆中的首地址) |
堆中 0003地址处的值,如下:
0003 | {"a", "b"} |
当传给 modifyArr1(t)时,新增了一个局部变量t,并将s1=0003的值传递给t,此时栈中变量如下:
arr1 | 0003 |
t | 0003 |
在modifyArr1(t)中的执行t[0]="c"时,修改了0003地址里第0个位置的值,如下:
0003 | {"c", "b"} |
执行modifyArr1(t)后,arr1和t的值都是0003,所以,arr1数组里的值变了