今天突然发现一个之前一直被我忽略了的问题,java方法的参数传递问题。之前只知道给方法传递实参时是传递变量的副本,在方法中改变参数的值时实际变量的值不受影响。其实,传递实参时分三种情况:
一、基本数据类型(数值类型、布尔类型)
基本数据类型在传递参数时是值传递,即将变量的值传递给形参,此时形参是一个与该变量值相同的数据,但不是同一个数据(可以看作是变量的副本),因此在方法中改变形参的值并不会影响实际变量的值。
public class A {
public void jia(int a) {
a++;
}
public static void main(String[] args) {
int a=1;
new A().jia(a);
System.out.println(a);//结果为1
}
}
从上面程序可以看出实际变量a的值并没有受到方法jia的影响。
二、引用数据类型
将引用数据类型变量传递给形参,实际传递了变量中存放的内存地址。此时,形参变量和实际变量指向同一地址内存,在方法中改变形参变量的值时,有两种情况:
1)改变形参变量中存放的地址
相当于将形参变量又指向别的内存区域,此时并不会影响实际变量中存放的地址值。
public class B {
public void jia(int[] a) {
int[] b=new int[] {100,200,300};
a=b;
}
public static void main(String[] args) {
int[] a=new int[] {1,2,3};
new B().jia(a);
System.out.println(a[0]+","+a[1]+","+a[2]);//结果是1,2,3
}
}
从上面程序可以看出,a变量仍指向原数组地址内存。
2)改变形参指向的地址的内容
调用了方法后,形参变量与实际变量指向同一块内存区域,此时若在方法中改变该内存区域内容,实际变量指向内存区域同时被改变(因为是同一块内存)
public class C {
public void jia(int[] a) {
a[0]++;
}
public static void main(String[] args) {
int[] a=new int[] {1,2,3};
new C().jia(a);
System.out.println(a[0]);//结果为2
}
}
从上面程序可以看出,数组a的第0个值被改变。
三、不可变类(如String、八大包装类)
不可变类也是引用数据类型,在参数传递时仍然是将其中存放的地址传给形参变量,但是不可变类对象的内容不可改变,一旦改变,就相当于创建了一个新的对象,并将改变后的内容赋给新对象,而原来的对象所在内存不会改变。
public class D {
public void jia(String a) {
a=a+"字符串被改变了";
}
public static void main(String[] args) {
String a="原字符串";
new D().jia(a);
System.out.println(a);//结果为 原字符串
}
}