java参数传递

在不同的java新闻组中,参数是传值还是传址一直是一个经常被争辩的话题。误解的中心是以下两个事实:<BR>

1、对象是传引用的<BR>

2、参数是传值的<BR>

这两个能够同时成立吗?一个字:是!在java中,你从来没有传递对象,你传递的仅仅是对象的引用!一句话,java是传引用的。然而,当你传递一个参数,那么只有一种参数传递机制:传值!<BR>

通常,当程序员讨论传值和传引用时,他们是指语言的参数传递机制,c++同时支持这两种机制,因此,以前使用过c++的程序员开始好像不能确定的java是如何传参数的。java语言为了事情变得简单只支持参数传值的机制。<BR>

java中的变量有两种类型:引用类型和原始类型。当他们被作为参数传递给方法时,他们都是传值的。这是一个非常重要的差别,下面的代码范例将说明这一点。<BR>

在继续前,我们有必要定义一下传值和传引用。传值意味着当参数被传递给一个方法或者函数时,方法或者函数接收到的是原始值的副本。因此,如果方法或者函数修改了参数,受影响的只是副本,原始值保持不变。<BR>

关于java中的参数传递的混乱是因为很多java程序员是从c++转变过来的。c++有引用和非引用类型的变量,并且分别是通过传引用和传值得。java语言有原始类型和对象引用,那么,按照逻辑,java对于原始类型使用传值而对引用是传引用的,就像c++一样。毕竟,你会想到如果你正在传递一个引用,那么它一定是传引用的。这是一个很诱惑人的想法,但是是错误的!<BR>

c++java中,当函数的参数不是引用时,你传递的是值得副本(传值)。但是对于引用类型就不同了。在c++中,当参数是引用类型,你传递的是引用或者内存地址(传引用),而在java中,传递一个引用类型的参数的结果只是传递引用的副本(传值)而非引用自身。这是一个非常重要的区别!java不考虑参数的类型,一律传递参数的副本。<BR>

仍然不信?如果java中是传引用,那么下面的范例中的swap方法将交换他们的参数。因为是传值,因此这个方法不是像期望的那样正常工作。<BR>

<pre>

classSwap

{

publicstaticvoidmain(Stringargs[])

{

Integera,b;

inti,j;

a=newInteger(10);

b=newInteger(50);

i=5;

j=9;

System.out.println("BeforeSwap,ais"+a);

System.out.println("BeforeSwap,bis"+b);

swap(a,b);

System.out.println("AfterSwapais"+a);

System.out.println("AfterSwapbis"+b);

System.out.println("BeforeSwapiis"+i);

System.out.println("BeforeSwapjis"+j);

swap(i,j);

System.out.println("AfterSwapiis"+i);

System.out.println("AfterSwapjis"+j);

}

publicstaticvoidswap(Integeria,Integerib)

{

Integertemp=ia;

ia=ib;

ib=temp;

}

publicstaticvoidswap(intli,intlj)

{

inttemp=li;

li=lj;

lj=temp;

}

}

</pre>

上面程序的输出是:<BR>

<PRE>

BeforeSwap,ais10

BeforeSwap,bis50

AfterSwapais10

AfterSwapbis50

BeforeSwapiis5

BeforeSwapjis9

AfterSwapiis5

AfterSwapjis9

</PRE>

因为swap方法接收到的是引用参数的副本(传值),对他们的修改不会反射到调用代码。<BR>

译者注:在传递引用和原始类型时还是有不同的,考虑以下的代码:

<pre>

classChange

{

publicstaticvoidmain(Stringargs[])

{

StringBuffera=newStringBuffer("ok");

inti;

i=5;

System.out.println("Beforechange,ais"+a);

change(a);

System.out.println("Afterchangeais"+a);

System.out.println("Beforechangeiis"+i);

change(i);

System.out.println("Afterchangeiis"+i);

}

publicstaticvoidchange(StringBufferia)

{

ia.append("ok?");

}

publicstaticvoidchange(intli)

{

li=10;

}

}

</pre>

程序的输出为:<BR>

<PRE>

Beforechange,aisok

Afterchangeaisokok?

Beforechangeiis5

Afterchangeiis5

</PRE>

,即如果传递的是引用,那么可以修改引用对象的内容,这个改变会影响到原来的对象,而传递的如果是原始类型则不会有影响。这个也是造成误解的原因之一吧。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值