JAVA的值传递和引用传递
1、问题:
今天上班发现一个有意思的事情,将一个int值传入一个方法中。方法内部对该值进行修改。重新打印输出,发现值未发生改变。代码如下:
public class test1 {
public static void changeNum(int a) {
a=2;
}
public static void main(String[] args) {
int a=1; //初始化为1
System.out.println("修改前的值>>>>>>>>>a="+a); //期望输出a=2
changeNum(a); //修改a=2
System.out.println("修改后的值<<<<<<<<<a="+a); //期望输出a=2
}
}
程序中原始值a=1,方法changeNum将a重新赋值为a=2。执行方法changeNum后,原以为a的值为2,但是实际打印结果为:
修改前的值>>>>>>>>>a=1
修改后的值<<<<<<<<<a=1
方法changeNum明明已经将a的值改为2,为什么输出还是1. 带着疑问查找了网上各种资料,最后发现原来是java参数传递惹的祸。
2、java值传递和引用传递:
上面代码中参数为int 类型,是基本数据类型为值传递,首先main方法初始化了a=1,main方法调用changeNum(a)时,其实是将a的值复制了一份a1给changeNum,此时方法体修改a1的值并不会影响原值。
值传递会将原值复制,修改方法参数值不会影响原值。
参数值为对象时,会将原值的地址(引用)当做参数传给新方法,类似C语言的指针,此时方法体获取的值为原值,方法体对操作参数对象,原数据随着发生变动。
基本类型作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝,原值是不会改变的。
对象和引用作为参数传递时,是把对象在内存中的地址拷贝了一份传给了参数。
String较为特殊,String为引用类型,但是传递时为值传递
3、修改原程序:
原程序中将a当做参数传到changeNum中,其实原值并未发生改变。此时如果想修改原值,可以使用return重新赋值,如下:
public class test1 {
public static int changeNum(int a) {
return a=2;
}
public static void main(String[] args) {
int a=1; //初始化为1
System.out.println("修改前的值>>>>>>>>>a="+a); //期望输出a=2
a=changeNum(a); //修改a=2
System.out.println("修改后的值<<<<<<<<<a="+a); //期望输出a=2
}
}
输出结果:
修改前的值>>>>>>>>>a=1
修改后的值<<<<<<<<<a=2
3、总结:
1、内存结构:
基本数据类型:使用栈内存。
String:栈内存存地址,堆内存存储实际空间
对象:栈内存存地址,堆内存存储实际空间
2、常量和变量:
基本数据类型:常量
String:常量
对象:无特殊要求时为变量
3、值传递:
基本数据类型:复制栈内存地址和名称传到新方法中,方法结束原值不变。
String:复制栈空间地址和堆空间地址传到新方法中,方法结束原值不变。
4、地址传递:
引用对象:复制栈内存到新方法中,和原地址指向同一内存空间,方法结束原内存空间变动
结论:
变量 有自己的地址 地址里存的值可变;
常量 有自己的地址 地址里的值不可变;
参考博客:https://www.cnblogs.com/boboooo/p/9066831.html