在我们调用方法时,有可能会需要向方法传递参数,参数一般是基本类型的变量或者是引用类型的变量。
基本类型
如果参数是基本类型的变量,则传递的是实参的值的副本(拷贝),在方法中改变形参的值,将不会影响到实参。
例如:
public class Test {
public static void test(int a,int b) {
a = a - 1;
b = b - 1;
System.out.println("a = " + a);
System.out.println("b = " + b);
}
public static void main(String[] args) {
int c = 10;
int d = 10;
test(c,d);
System.out.println("c = " + c);
System.out.println("d = " + d);
}
}
运行结果:
上面的例子中,将c和d作为实参传给形参a和b,并且在方法体中改变了a和b的值,但实参c和d的值并没有改变。那是因为在基本类型参数传递过程中,只是将c和d的值分别拷贝一份给a和b,它们都是独立的,改变形参的值不会影响到实参。
引用类型
如果参数是引用类型的变量,则传递的是引用的值的副本,因为在引用中保存的是对象的地址,所以所以传递的就是地址的拷贝。在方法中改变形参,将会影响到实参引用的对象。
例如:
public class Test {
public static void test(A a) {
a.setA(9);
System.out.println("a = " + a.getA());
}
public static void main(String[] args) {
A a = new A();
a.setA(10);
test(a);
System.out.println("a = " + a.getA());
}
}
class A{
private int a;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
运行结果:
在上面的例子中,将类A对象的一个引用a作为实参传给test方法中的形参a,并且在方法体中调用方法改变了对象中实例变量a的值,这个改变反应到了实际对象上。
那是因为在基本类型参数传递过程中,是将实参引用中保存的对象的地址拷贝一份给形参,实参和形参都指向同一个对象,所以通过形参改变对象会影响到实际的对象。
特殊情况
public class Test {
public static void test(String str) {
str = str + "world";
System.out.println(str);
}
public static void main(String[] args) {
String str = "hello";
test(str);
System.out.println(str);
}
}
运行结果:
String类型的字符串也是对象,那么为什么通过新参改变字符串对象,原来的对象并没有改变呢?
那是因为String是不可变类,在方法体中改变字符串对象,将会构造一个新的对象,并将形参指向新的字符串对象,原来的对象不会改变。