值传递的代码讲解
java中都是值传递,它是继承于c++但是移除出了很多难懂的语法,
js也是值传递;
1.啥叫值传递啊:
顾名思义,就是值的传递,基本类型,引用类型,在创建出来,就是存在于当前方法所在的栈帧,就是调用其他方法,传的是引用地址,不是真实对象(看代码的输出就懂了)
2.引用类型传引用?
这是坑,Java只有值传递,学过C++知道,C++有值传递,引用传递,Java已经摒弃了引用传递,因为我用变量接一下多好,简洁,不花里胡哨。
上代码:
package com.qcby.studentManeger;
public class Test {
public static void main(String[] args)
{
//第一部分
int a=10;
int b=20;
exchange(a,b);
//交换的是exchange的新开的地址,exchange战栈帧弹出
System.out.println(a);//10
System.out.println(b);//20
//第二部分
//值引用,exchange的新开的地址a1^,b1^,
//exchange战栈帧弹出,裂开,没有接返回值,没法把改变应用到实际的a1,b1
// 虽然是地址换来换去,exchange栈帧弹出,还是没改变main的a1,b1
Student a1=new Student();
Student b1=new Student();
a1.name="张三";
b1.name="李四";
exchange(a1,b1);
System.out.println(a1);//张三
System.out.println(b1);//李四
//第三部分
//值引用,但是堆中的对象内容只有一份,可以变
exchange1(a1,b1);
System.out.println(a1);//张三
System.out.println(b1);//李四
}
public static void exchange(int a,int b){
int temp=a;
a=b;
b=temp;
}
public static void exchange(Student a,Student b){
Student temp=a;
a=b;
b=temp;
}
public static void exchange1(Student a,Student b){
String temp=a.name;
a.name=b.name;
b.name=temp;
}
}
ok,还有解释
代码三部分,对应三种情况:
三张图,对应在jvm的存储情况
左侧是栈(存局部变量的),右侧是堆(存对象实际内容)
第一种:
第一张图
基础类型值传递,并没有在main函数接收,就是没int ans=exchange(a,b)
,导致exchange的新开的内存a1’,b1’,虽然变了,但直接弹出栈,没有把结果返回,导致函数无用运行。
第二种:
第二张图
引用类型值传递,想改变引用指向,也就是a1,b1存储的地址,
这个是引用类型,保存的是地址(如:0x1234),也是在栈里存啊,也没有在main函数接收,就是和基础类型一样,导致exchange的新开的内存a1’,b1’,虽然变了,但直接弹出栈,没有把地址改变结果返回,导致函数无用运行。
第三种
第三张图
也是引用型传递,咋这个就变了,因为对象地址在栈里,是新创建的,可以有多份,互不影响。例如:a1,b1不会受a1’,b1’影响,因为当前实参不受形参影响,a1’,b1’只是复制品,你随便搞多人运动,你就算a1'=null
,a1也不变。
所谓的不变,只是存在栈里的地址不变,我a1’虽然是复制品,但我有a1的地址啊,我可以去堆里找对象啊,找到了我就可以修改啊。
再通俗点:
-
堆里对象就像房子,a1是正门,a1’是新开的门,a1’这个新门咋样,a1正门不受影响 ,就是第二部分的含义
-
新门也是门,可以进去修东西啊,就是第三部分的修改对象