Java方法签名中的参数被称为形参,而方法实际调用时传递到形参的值称为实参。Java的参数传递机制只有值传递,所谓值传递就会将实参的值副本传递到方法内,而参数本身不受到任何影响。比如:
示例一:
public class Test {
public static void main(String[] args) {
int a = 1;
int b = 2;
conver(a,b);
System.out.println("a = "+String.valueOf(a)+ ";b = "+String.valueOf(b));
}
public static void conver(int a,int b){
a=3;
b=4;
System.out.println("重新赋值后:a = "+String.valueOf(a)+ ";b = "+String.valueOf(b));
}
}
打印结果:
重新赋值后:a = 3;b = 4
a = 1;b = 2
示例一中,a和b是conver方法的形参,main方法调用conver传入的实参a=1,b=2。conver方法中重新给参数赋值a=3,b=4,根据打印结果来看,a和b的值只是在conver方法中发生了变化,而实际传递的值未发生变化,这也证明了Java方法的传递机制。
示例二:
public class Test2 {
public static void main(String[] args) {
User user = new User();
user.age = 18;
user.name = "hh";
conver(user);
System.out.println("age = " + String.valueOf(user.age) + ";name = " + user.name);
}
public static void conver(User user) {
user.age = 20;
user.name = "xx";
System.out.println("age = " + String.valueOf(user.age) + ";name = " + user.name);
}
public static class User {
int age;
String name;
}
}
//打印结果
age = 20;name = xx
age = 20;name = xx
示例二中,conver方法中形参为引用对象user,从打印结果中看出,修改user的值后发现user值的发生了变化。这好像又不符合Java的参数传递机制。
两种不同类型的参数传递,同样的操作对于参数本身却有不同的效果。究其原因是因为两个参数在初始化存储位置不同和运行时不同导致。两种参数一种是基本数据类型,一种是引用类型。在Java基础—类变量、实例变量、局部变量一种文中,局部变量随着进入方法、构造器、代码块时被创建,退出时被销毁这里传入方法内的确切应该是指变量的一个副本。根据JVM的运行原理,在方法入栈的时,变量的副本也会在栈中创建。基本数据类型,创建的是变量本身值的副本,而引用数据类型创建的是引用的副本。来看下下面的两个流程图:
一、基本数据类型:
二、引用数据类型:
从图中可以看出,基本数据类型修改参数值是直接修改方法栈中的副本值,参数对象本身没有变化。而引用数据类型修改的参数,因对象引用最终指向的都是堆中的真正的对象空间,所以在方法内修改引用类型参数,参数本身也发生了变化。对示例二代码中稍作修改,消除对象引用关系,而对象值也会发生变化,这也证明了,参数为引用数据类型时,入栈的确实也是副本数据,不过不是参数本身的副本而是参数引用的副本,结合引用对象在堆中创建,参数为引用数据类型时也符合Java值传递的机制。
public class Test2 {
public static void main(String[] args) {
User user = new User();
user.age = 18;
user.name = "hh";
conver(user);
System.out.println("age = " + String.valueOf(user.age) + ";name = " + user.name);
}
public static void conver(User user) {
user.age = 20;
user.name = "xx";
System.out.println("age = " + String.valueOf(user.age) + ";name = " + user.name);
user = null;
}
public static class User {
int age;
String name;
}
}
//打印结果
age = 20;name = xx
age = 20;name = xx
关联扩展: