争论话题:Java传值还是传引用?

辞职专心找工作了。没事干就开始啃那本买了一年多都还没看的Thinking In Java。巩固巩固基础吧 :D
Java传值还是传引用好像自Java出现后就一直存在争论,大家各持己见。这里阐述下自己的理解,算是对Thinking in Java的一个读书笔记。
一.预备知识
在Thinking in Java的第二章里,提到了Java将对象存放到了哪里。这里主要看栈和堆。
看下面几行代码的区别。

int i = 1;
String str = new String("Hello");

从第二行代码里又可以引申如一个经典的面试题,这里创建了几个String对象。这里不做讨论。
大家都知道左边的是引用,指向了右边的实际的值。但是在Java里面这两段有区别吗?看图。

[img]/upload/attachment/123571/f4de8861-a5b5-3500-96d7-800b040a632c.png[/img]

从图上可以看出,栈里的每个值又可以看成是一个个的键值对。
对于

int i = 1;

来说,键就是变量i,而值就是1。
而对于

String str = new String("Hello");

来说,键是变量str,而值是new String("Hello");在堆里的地址。(在Java中所有new出来的东东都在堆里面)

二.传值还是传引用?
好,知道了上面的区别,对于传值和传引用的理解就很有帮助了。
看下面的代码。

public class Change {
public void change(int i){
i = 2;
}

public void change(String str){
str = "Ivan";
}

public void change(StringBuffer str){
str.append(" World");
}
}

那么将上面的i和str传入如下的三个方法中是否有作用呢?(这里添加了一个StringBuffer,是因为你无法改变String)
再来看下Java中的方法如何执行的。在Thinking in Java第七章中,提到了一点。[color=red]方法的执行是将参数压入栈中,跳至方法代码处执行方法,然后跳回并清理栈中的参数,处理返回值。[/color]从这里可以知道,方法的参数在栈里面也有对应的存储空间,而值就是传入的i和str在栈中所对应的值。[color=red]也就是说,是i和str的一个拷贝。[/color]
那么来看上面的三个方法。
对于第一个方法,从上面可以知道,这里的i和原来的i已经不是同一个i了,所以这里操作的是完全不同的东东。
第二个方法和第一个相似,根据前面知道,这里的str持有的是指向"Hello"的引用。但是这里直接将这个引用改成了指向"Ivan"的,原来的str还是指向"Hello",对原来的str没有一点影响。
第三个方法是是直接操作了str所指向的那个"Hello",因为原来的str指向同样的"Hello",所以这就会改变原来str的值了。

三.总结
从上面可以知道,Java是将栈里的值拷贝了一份作为参数传到了方法里面。对于基本类型就是传的值了,而对于对象类型就是引用了。不管传的是值还是引用,都是栈里的拷贝。记住这一点应该就不会再有什么疑问了 :D

四.关于数组
继续看Thinking in Java,关于数组一节的介绍,有这么一句。[color=red]无论使用的是哪种类型的数组,数组标示符其实只是一个引用,指向在堆中创建的一个真实对象,这个(数组)对象用以保存指向其他对象的引用。[/color]
再结合上面的内容,下面两个方法能否改变值应该能知道吧 :D

public void change(int[] i){
i[0]=1;
}

public void change(String[] str){
str[0]="Ivan";
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值