java形参的改变会影响实参吗?
昨天做题的时候遇到了这个问题(如图所示),传入的参数是int[]数组,实参跟着形参一起改变了。但是之前传入int型参数时形参的改变是不会影响实参的。所以想探究一下这个问题,到底什么情况下形参的改变会影响实参。
- 形参和实参:首先分清楚形参和实参区别。简要来说形参就是定义方法的时候用到的参数,方法被调用时就是靠它来接收传入的参数。例如上图中的reverse(int[] arr,int k),这里的arr和k就是形参。实参就是调用方法时传进去的参数。例如上图中的reverse(arr,k),这里的arr和k是实参。
- 值传递和引用传递: 值传递就是在调用方法时,实参把它的值给到形参,形参把这个值拷贝一份,再拿到方法里用。所以传参之后它俩互不相关了,形参的改变就不会影响到实参。而引用传递,在调用方法时传递的是值的引用,也就是说形参拿到的是实参所对应的内存空间的地址,那么传参之后形参和实参指向的就是同一个内存空间,理所当然实参会跟形参一起改变。
分清了值传递和引用传递之后再来看文章开头说的int[]和int类型的参数有什么区别。
当参数为int[]数组:
// int[]数组作为参数
public static void main(String[] args){
int[] arr = {3,2,1,4};
reverse(arr,3);
System.out.println("翻转后数组为:");
for(int i : arr) {
System.out.print(i);
}
}
//翻转数组从0到k-1
public static void reverse(int[] arr,int k) {
int i = 0,j=k-1;
int temp=0;
while(i<j) {
temp= arr[i];
arr[i]=arr[j];
arr[j]=temp;
i++;
j--;
}
}
输出结果:
可见调用方法之后实参跟着形参一起被修改了。
当参数为int数值:
// 当参数为int型
public static void main(String[] args){
int a = 0;
changeInt(a);
System.out.println("主函数中实参a的值为:"+a);
}
//修改数的值
public static void changeInt(int a) {
a=100;
System.out.println("changeInt方法中形参a的值为"+a);
}
输出结果:
可见形参虽然被修改了,但是实参还是原来的值,并没有一起被修改。
发生这样的情况,原因在于:数组是引用类型,它作为参数时发生的传递是引用传递;而int是基本类型,它作为参数时发生的传递是值传递。
特别:需要注意的是封装类和String类比较特殊,虽然是引用类型,但是由于其本质是由final修饰的,不能被修改,所以作为传参时实参是不会跟随形参发生改变的。
例如Integer作为参数:
public static void main(String[] args){
Integer a = 0;
changeInt(a);
System.out.println("主函数中实参a的值为:"+a);
}
//修改数的值
public static void changeInt(Integer a) {
a=100;
System.out.println("changeInt方法中形参a的值为"+a);
}
输出结果:
String作为参数:
public static void main(String[] args){
String a = "0";
changeString(a);
System.out.println("主函数中实参a的值为:"+a);
}
//修改数的值
public static void changeString(String a) {
a="100";
System.out.println("changeString方法中形参a的值为"+a);
}
输出结果:
总结:例如数组之类的引用类型作为参数时,形参的修改会影响实参;而基本类型和特别的引用类型(封装类、String类)作为参数时,形参的修改不会影响实参。
关于封装类的地址传递参考链接: Interger是值传递还是地址(引用)传递?