问题: Java的参数传递的是值还是引用?
我们经常会被问到这样的问题,当我调用某个方法时,通过参数传递过去的是变量本身,还是一个变量的复制品?问题的答案留到讨论后给出。
首先,你需要了解下java变量的分类:java中的变量分为
基本类型接口类型类类型数组类型其中后面三种统称为引用类型,而基本类型分为三种,
数字类型booleanreturnAddress数字类型又分为
浮点类型整数类型浮点整数又有具体的内容,这里不再展开说明。其中,returnAddress是java虚拟机内部使用的类型,它被用来实现java程序中finally子句。这里主要看引用类型和基本类型数字类型情况(boolean类型的情况和基本类型一致).
先看参数为基本类型的情况:
01 public class Demo1 { 02 public void swap(int a, int b) { 03 a = a ^ b; 04 b = a ^ b; 05 a = a ^ b; 06 System.out.println("swap: a=" + a + ",b=" + b); 07 } 08 09 public static void main(String[] args) { 10 Demo1 demo1 = new Demo1(); 11 int a = 1; 12 int b = 2; 13 demo1.swap(a, b); 14 System.out.println("main: a=" + a + ",b=" + b); 15 } 16}输出
1swap: a=2,b=1 2main: a=1,b=2上面的代码想通过swap交互a和b的值,在swap内部,变量a和b已经交换成功了,但在main中a和b的值依然是原来的值.
再看参数为引用的情况:
01</pre> 02 <pre>public class Demo2 { 03 public void swap(StringBuffer a,StringBuffer b){ 04 StringBuffer c = a; 05 a=b; 06 b=c; 07 System.out.println("swap: a="+a+",b="+b); 08 } 09 10 public static void main(String[] args) { 11 StringBuffer a = new StringBuffer("a"); 12 StringBuffer b = new StringBuffer("b"); 13 Demo2 demo2 = new Demo2(); 14 demo2.swap(a, b); 15 System.out.println("main: a="+a+",b="+b); 16 } 17}</pre> 18<pre>大家可以先思考下,上面的输出是什么?
输出: swap: a=b,b=a main: a=a,b=b
和参数为基本类型的情况结果是一致的. 为什么会出现这种情况呢?
我们来分析下上面的参数传递过程,以Demo2为例:
图1是swap未计算前的参数值,
图2是swap计算后的参数值.
从图中可以看出,swap的计算过程只能改变swap内部变量a和b的值,不能改变main中的a和b变量的引用值,换言之,参数的传递只能传值,不存在传引用一说.
请注意,上面我说不能改变a和b变量的引用值,可没说不能改变a和b指向的对象的值.再看下面的例子:
01</pre> 02 public class Demo3 { 03 public void swap(StringBuffer a,StringBuffer b){ 04 a.append(b); 05 StringBuffer c = a; 06 a=b; 07 b=c; 08 System.out.println("swap: a="+a+",b="+b); 09 } 10 public static void main(String[] args) { 11 StringBuffer a = new StringBuffer("a"); 12 StringBuffer b = new StringBuffer("b"); 13 Demo3 demo3 = new Demo3(); 14 demo3.swap(a, b); 15 System.out.println("swap: a="+a+",b="+b); 16 } 17} 18这个会输出什么呢? 19 20swap: a=b,b=ab 21swap: a=ab,b=b这个就是上面所说的,在swap内部的计算过程中,改变了main.a所指向对象的值.
就像下面的图所描述的那样:
、
但根本上,swap不能改变main中a和b的引用值.
另外贴一句sun公司官方文档上的描述这一问题的原话:
Java is always pass-by-value.when object is passed as a argument, be careful with that it is also the copy of reference
所以,现在你应该知道,java传递的只会是值,没有传递引用.
转载自 并发编程网 - ifeve.com