java ref 值传递_Java其实都是值传递?

0608f3072fa5c844526e31e67fb0df46.png

在Java中值传递和引用传递是不一样的,怎么个不一样法呢?他们在内存当中的结构是怎么样的我们通过四个示例,来给大家说道说道,

示例一:值传递

publicclassValueDemo{ publicstaticvoidmain(String[] args){ int x = 10;//我们定义了一个基本数据类型的局部变量 是存在栈里边的 method(x) ; System.out.println(“x=”+x) ; } publicstaticvoidmethod(int mx){ mx = 20; }}结果是多少呢?是10,为什么是10呢。

e44731580f7afc1c40eb89194058ad81.png

因为基本数据类型的变量是存在栈内存的,所以method入栈,然后传值的时候,是把x复制一份传给mx,然后method方法mx变成20,是复制品变成了20,然而x还是10.其实Java当中都是值传递,为什么要分值传递和引用传递呢?接着往下看

示例二:引用传递

publicclassRefDemo1{ publicstaticvoidmain(String[] args){ Duck d = new Duck(); method(d) ; System.out.println(“Duck age = ”+d.age) ; } publicstaticvoidmethod(Duck duck){ duck.age = 5; }}classDuck{ int age = 2; //省略封装}其实引用传递也是一种值传递,只不过他的值不是具体的数据,他的值是一个地址,所以叫它引用传递 这里我们写了一个类鸭子类,它有一个年龄2,然后我们用产生对象的方法new 关键字 ,new了一个鸭子,然后将这个实例d,传进了method,然后将duck的age变成了5,然后再输出鸭子的年龄,结果是什么呢?肯定不是2了,如果是2引用传递就没有意义了和值传递不就一样了吗啊哈哈哈!最后的结果是5,为啥呢?看我再给你分析一波!先来一张艺术品画图

0c776200c667742731316e334061e007.png

因为呀这个duck是引用类型的数据,所以它在执行完Duck d = new Duck()内存结构是栈内存里存的内存地址,堆内存里存的属性啥的,method方法执行的时候,它还是复制了一份传进去,这次它复制的是栈内存里的地址,然后method方法改变的age,因为是同一个地址,所以d.age就被更改成了5.你以为这样值传递和引用传递就完了,四种情况呢,还有两种没说呢!

示例三:String传递

publicclassRefDemo2{ publicstaticvoidmain(String[] args){ String name = “小飞”; method(name) ; System.out.println(“name=”+name) ; } publicstaticvoidmethod(String sname){ sname = “小备”; }}示例三的结果为啥输出的是小飞呢?字符串不是引用类型的变量吗?what,我们继续看内存结构

db42a9e5122f779b42ec906600e91a35.png

because字符串本身就是个对象,方法传值的时候 和以前一样也是传的地址,不一样的是sname=”小备”,”小备”它就相当于创建了个对象,相当于new了一个对象,小飞和小备不是一个实例了,sname=”小备”sname的指向就变成了小备,而name的指向还是”小飞”,这也是字符串一个特殊的地方

示例四:String传递

publicclassRefDemo3{ publicstaticvoidmain(String[] args){ Person p = new Person(); method(p) ; System.out.println(“person name= ”+p.name) ; } publicstaticvoidmethod(Person p ){ p.name = “备备”; }}classPerson{ String name = “飞飞”; //省略封装}这次如果让我猜的话 应该就是备备了,为啥是备备了呢?接着上图

569429f97d57445a1562b98529160c7b.png

这个图还是挺复杂的,一步一步的分析,先实例化一个Person p,栈内存里存的p的地址,堆里面存的是Person这个实例,然后p里面的name它也是一个引用类型的变量所以name存的也是一个地址,然后它指向了”飞飞”这块地址为0x0055的内存,传给method的依然是0x0044这个地址,然后p.name=”备备”,name的指向由指向0x0044,指向了备备的内存地址0x0066,p的name的地址变了,加黑的那一句话!理解关键就是分析完毕!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值