Java参数传递:到底是传值还是传引用

来源:互联网 发布:0708赛季nba总决赛数据 编辑:程序博客网 时间:2024/05/17 22:10

这个问题一般都是先学了C++而后接触Java的同学经常问的问题。

有一个学弟问我这个问题:Java中函数的参数传递的是值还是引用?

我想到,我之前在学习《Java编程思想》的时候,书中在“一切都是对象”这一章节,当讲到函数的参数传递时,有这么一句话:“像Java中任何传递对象的场合一样,这里传递的实际上也是引用”。于是我不假思索的回答:传递的是引用,而且在Java中,一切都是引用传递

于是他拿来一段一段代码问我:

public static void swap(int a,int b){int temp = a;a = b;b = temp;}
这个swap()方法原本的意图是实现参数a、b交换,但是实际是:

public call(){int a=0,b=7;swap(a,b);System.out.println(a+"  "+b);}

输出结果是:

0  7

也就是说,变量交换失败。如果说在Java中“一切传递都是引用的传递”,结果为什么是这样呢?

显然我的说法是错误的(蓝色部分)。

那么到底是哪里错了?书中的讲解难道有误?下面罗列出我犯的错误:

1.首先基本数据类型并非使用引用操控。

在Java中,可以把我们实际使用到的变量分为两类:

  • 引用类型。比如String s,这里只是创建了一个String类型的引用,而不是对象。在Java中,“一切皆为对象”,而我们实际操纵对象是通过“引用”。就好比是用遥控器来操控电视机一样,遥控器和电视机显然是两码事。
  • 基础类型。Java中有8种(实际上还有void)基本类型,这种类型的变量不是用new创建,而是创建一个并非引用的自动变量,这个变量本身直接存储“值”。
  • 这两种类型的变量的共同之处在于:他们都是存储在堆栈中。
因此,很显然,这一点我就已经错了:我把书中的“引用传递”也用在了基本类型变量上,而基本类型变量根本不是引用。
当然,问题的根结并不在此。
2.Java中的任何事物都是按值传递的。
这就有点让人困惑了,对象不是传递的引用吗?
我的理解是,Java中所说的“引用”并非C++用户所指的“引用”,也就是传“地址”。Java中的引用是指“对象引用”,是存储在堆栈中的,当把对象作为参数传给方法时,实际上是复制了这个引用的副本。而对这个引用,我们有两种操作:
  • 对引用本身进行操作。一般就是给引用赋值,实际上只是让实参的一个副本指向一个新的对象,而原本的实参引用并没有改变。
  • 使用引用操作对象。因为这里的参数引用是指向实参对象的,所以通过这个参数,给对象“发送信息”,是会实现对对象的改变。我觉得这也是最让人误以为这是“传地址”的地方。
区分这两种引用操作,我觉得会有助于理解为什么说这里是传递“引用“,同时也是传值了。
3.那么如前所说,基本类型并不是用引用操作,那么基本类型参数是传递什么?
答案是:也是值传递。基本类型变量子啊堆栈中创建一个变量,同时直接存储”值“,因此基本类型作为参数时,是直接传递变量的一个副本,也就是所谓的值传递。

0 0
原创粉丝点击