java参数传递的方法有两种讨论,从不同的角度来看,两种说法都是对的,所以不必拘泥于到底是值传递还是引用传递,主要看你想达到什么目的。
- 值传递
java在传递基本数据类型的数据的时候,传递的是这个数据的值的副本。
java在传递引用数据类型的数据的时候,传递的是这个数据对象的句柄的副本
可以说,java中一切参数的传递,都是传递这个参数的副本,无论是基本数据类型还是引用数据类型。但是前提是,如果传递的参数是引用数据类型的话,我们在被传递的方法里处理的是句柄,而不是句柄所指向的对象。这里举例说明
public class Alias2 {
int i;
Alias2(int i){this.i = i;}
static void f(Alias2 b){
b= new Alias2(5);
b.i++;
}
public static void main(String[] args) {
Alias2 a = new Alias2(3);
System.out.println("a.i="+a.i); //a.i=3
f(a);
System.out.println("a.i="+a.i); //a.i=3
}
}
从上述代码可以证明,a是引用类型数据对象的句柄,指向的对象时Alias的对象。当a作为参数传递的时候,方法里得到的是对象的句柄b,这个b是a复制过来的,所以他们指向同一个对象,但是方法f()中并没有处理b指向的对象,而是处理b这一个句柄,把句柄指向的对象改了,方法执行f()完毕后回到main方法里,根据最终的打印结果我们可以发现,a指向的对象的属性 i 仍然是3没有改变,所以可以说 java 中一切参数的传递,都是传递这个参数的副本。
- 引用传递
java在传递基本数据类型数据的时候,是值传递,传递的是基本数据类型数据的值的副本
java在传递引用数据类型数据的时候,是引用传递,传递的引用数据类型的句柄所指向的对象
为什么说传递引用数据类型数据的时候是引用传递呢,因为上面的值传递说了,传递的都是参数的副本,但是,java在传递引用数据类型的时候,传递的是对象,却不是对象的副本,不符合值传递的规则。举例说明
public class Alias2 {
int i;
Alias2(int i){this.i = i;}
static void f(Alias2 b){
b.i++;
}
public static void main(String[] args) {
Alias2 a = new Alias2(3);
System.out.println("a.i="+a.i); //a.i=3
f(a);
System.out.println("a.i="+a.i); //a.i=4
}
}
从上述代码的句柄a指向的对象的属性 i 的值改变就可以看出,对象经过f()方法,就已经被修改了属性,如果是值传递,传递的是对象的副本的话,就不会出现这样的情况,所以说,java在传递引用数据类型数据的时候,不是值传递。
- 结果:两种说法如果说都成立,那么都得有各自的前提。还是看你想把参数怎样去处理,但是一般来说,第二种方式更能让人理解一点。