结论
java中方法参数传递方式是按值传递。
如果参数是基本类型,传递的是基本类型的字面量值的拷贝。
如果参数是引用类型,传递的是该参量所引用的对象在堆中地址值的拷贝。
代码证明
class Man {
public String name;
public int age;
public Man(String name, int age) {
this.name = name;
this.age = age;
}
public void print() {
System.out.print("[name: " + this.name);
System.out.print(",age: " + age + "]\n");
}
}
class MathPlus {
public void change(int a) {
a = 1;
}
public void change(Man a) {
a = new Man(a.name, 100);
}
public void ageChange(Man a){
a.age = 100;
}
}
public class Main {
public static void main(String[] args) {
System.out.println("基本类型的参数传递:");
int a = 5;
System.out.println("修改前 a = " + a);
MathPlus math = new MathPlus();
math.change(a);
System.out.println("修改后 a = " + a);
System.out.println("----------------------");
System.out.println("引用类型的参数传递(修改参数指向的地址):");
Man ss = new Man("ss", 15);
System.out.print("修改前: ss = ");
ss.print();
System.out.print("修改后:ss = ");
math.change(ss);
ss.print();
System.out.println("----------------------");
System.out.println("引用类型的参数传递(修改参数指向地址所指向的内容):");
System.out.print("修改前: ss = ");
ss.print();
System.out.print("修改后:ss = ");
math.ageChange(ss);
ss.print();
}
}
返回结果
基本类型的参数传递:
修改前 a = 5
修改后 a = 5
----------------------
引用类型的参数传递(修改参数指向的地址):
修改前: ss = [name: ss,age: 15]
修改后:ss = [name: ss,age: 15]
----------------------
引用类型的参数传递(修改参数指向地址所指向的内容):
修改前: ss = [name: ss,age: 15]
修改后:ss = [name: ss,age: 100]
可见,java中的没有c++中意义上的按引用传递(此时,参数名相当于原来实参的别名,能完全代表原来的参数),在java中,内置数据类型,按值传递;引用数据类型也按值传递,但是传递的是引用类型的地址,也即按值传递中的按地址传递。
这样java的参数传递特点就明晰了,对引用类型进行按地址传递,既能保证可以快速的修改原变量,同时又限制了修改的能力。不允许其整个完全被修改了。
我猜想,java设计者认为,若是一个对象所拥有的方法不足以支持它修改成任意模样,那么它就是不合格的类型。而当传入变量自身拥有的方法就足以修改它了。就不必搞全功能的引用传递,彻底修改原变量(所在地址都变了)。
所以为简单考虑,java没有全功能的按引用传递,只有按地址传递(实质仍是按值传递)。