先说结论
java中方法参数传递方式是按值传递。
如果参数是基本类型,传递的是基本类型的字面量值的拷贝。
如果参数是引用类型,传递的是该参量所引用的对象在堆中地址值的拷贝。
再来举例说明
基本类型作为参数传递
public static void main(String[] args) {
//基本类型作为参数传递
int num = 2;
System.out.println("before change , num = " + num);
changeData(num);
System.out.println("after change , num = " + num);
}
public static void changeData(int num) {
num = 10;
}
输出结果为
before change , num = 2
after change , num = 2
通过这个例子,说明基本数据类型作为参数传递时,传递的是值得拷贝,无论怎么改变这个拷贝,原值是不会改变的。
对象作为参数传递
public static void main(String[] args) {
//对象作为参数传递
A a = new A("hello");
System.out.println("before change , a.str = " + a.str);
changeData(a);
System.out.println("after change , a.str = " + a.str);
}
public static void changeData(A a) {
a.str = "hi";
}
class A {
public String str;
public A(String str) {
this.str = str;
}
}
输出结果为
before change , a.str = hello
after change , a.str = hi
从结果来看,对象a被改变了,那么是不是调用changeData方法时,传入的就是a对象本身呢?
答案是否定的。
下面我们进行分析,程序从main方法开始执行,首先创建了一个A对象,并定义了一个a引用变量来指向A对象。
接下来,调用changeData方法,a变量作为实参传入changeData方法,赋值给changeData方法里的形参,从而完成changeData方法的a形参的初始化。
从上图可以看出,这种参数传递方式也是值传递,将main方法中a的副本传入changeData方法,a是一个引用变量,所以并未复制A对象。
那么,当执行changeData方法时,由于a只是一个引用变量,所以实际操作的还是堆内存中的A对象。因此,不管是操作main中的a,还是操作changeData方法中的a,实际操作的都是堆内存中的A对象,是同一个对象。
所以,当changeData方法中改变了a变量引用的A对象的str值后,main方法中a变量所引用的A对象的str值也被改变了。
TODO
下面程序的输出结果是什么?
public class JavaDemo {
public static void main(String[] args) {
String str = new String("ada");
char[] ch = { 'a', 'b', 'c' };
change(str,ch);
System.out.print(str +" and ");
System.out.print(ch);
}
public static void change(String str, char ch[]) {
str = "ada 111";
ch[0] = 'd';
}
}