前言
当方法传递的参数是基本数据类型时,是值传递. 当方法传递的参数是引用数据类型时,是地址传递一、当方法传递的参数是基本数据类型时
有如下代码:
public class Demo1 {
public static void main(String[] args) {
int a=10;
System.out.println("调用change前"+a);
change(a);
System.out.println("调用change后"+a);
}
public static void change(int a ){
a=20;
}
}
运行结果
调用change前10
调用change后10
从结果分析来看对于基本数据类型来说,形参的改变,不会影响实际参数的值.
我们再从执行的内存图分析:
可以看出类等change方法弹栈之后,我们打印a的值依然是main方法中a的值10;
二、当传递的参数是引用数据类型时
有如下代码:
public class Demo2 {
public static void main(String[] args) {
int[] arr={10,20,30};
System.out.println("调用change前"+arr[1]);
change(arr);
System.out.println("调用change后"+arr[1]);
}
private static void change(int[] arr) {
arr[1]=200;
}
}
运行的结果是:
调用change前20
调用change后200
分析下运行时内存图的情况
从内存图中可以看出,引用数据类型的传参,传入的是地址值,内存中会造成两个引用指向同一个内存的效果,所以即使方法弹栈,堆内存中的数据也已经是改变后的结果 .
三.当传递的参数是字符串时
String虽然是引用数据类型,但在传递参数时和基本数据类型的特征保持一致.
因为String字符串是在常量池中的,并且一旦创建不能改变,如果重新给变量赋值,会重新创建新的空间.
代码如下:
public static void main(String[] args) {
String s="AAA";
System.out.println("调用change前"+s);
change(s);
System.out.println("调用change后"+s);
}
private static void change(String s) {
s="abc";
}
运行结果:
调用change前AAA
调用change后AAA
如下图
可以看出调用change方法的时候如果改变字符串的值,将会在常量池中重新创建出一个"abc"空间,并未改变原来001所指向的内容.
总结
1.基本数据类型的参数,形式参数的改变,不影响实际参数 ,本质是因为每个方法在栈内存中,都会有独立的栈空间,方法运行结束后就会弹栈消失
2.对于引用类型的参数,形式参数的改变,影响实际参数的值 ,本质是因为引用数据类型的传参,传入的是地址值,内存中会造成两个引用指向同一个内存的效果,所以即使方法弹栈,堆内存中的数据也已经是改变后的结果
3.对于String,传递参数时和基本数据类型的特征保持一致.