分享
 
 
 

Java “Pass by value” 解析

王朝java/jsp·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

Java “Pass by value” 解析

我在许多论坛和文章的答复上看到很多人都认为Java是pass by reference的,但我查了些资料,确实Java是pass by value的。如果你已了解java是pass by vlaue而非pass by reference的,那么你就可以pass这篇文章了,看其他你喜欢的文章去吧!如果你不以为Java是pass by vlaue或还坚信Java是pass by reference的,那么就跟着我的思路走一下吧。我会让你了解Java到底是pass by value还是pass by referenve。本人是个菜鸟,只是把自己所学的东西写出来给同级别的菜鸟学习学习。望高手看了多多指教,不要见笑。

Java是使用“pass by value”『函数调用』方式,这常常造成许多人迷惑。在所有地点,Java都严格采用pass by value。让我们来看一个简单的例子:

清单一:

class Param {

public static void main (String[] args) {

int x = 5;

triple(x);

System.out.println ("x after triple: " + x);

}

private static void triple (int arg) {

arg = arg * 3;

System.out.println ("arg in triple: " + arg);

}

}

会产生这样的输出:

arg in triple: 15

x after triple: 5

这段代码只是传入一个int而已,还不至于让人糊涂。但如果参数中传递的是一个对象,就可能把你弄迷糊了。如果我在程序中以Date对象表示日期,那么程序看起来想这样:

清单二:

import java.util.*;

class Param {

public static void main (String[] args) {

Date d1 = new Date ("1 Jan 2004");

nextDateUpdate (d1);

System.out.println ("d1 after nextDay: " + d1);

Date d2 = new Date ("1 Jan 2004");

nextDateReplace (d2);

System.out.println ("d2 agter nextDay: " + d2);

}

private static void nextDateUpdate (Date arg) {

arg.setDate (arg.getDate() + 1);

System.out.println ("arg in nextDay: " + arg);

}

private static void nextDateReplace (Date arg) {

arg = new Date (arg.getYear(),arg.getMonth(),arg.getDate() + 1);

System.out.println ("arg int nextDay: " + arg);

}

}

会产生这样的输出:

arg in nextDay: Jan 02 00:00:00 CST 2004

d1 after nextDay: Jan 02 00:00:00 CST 2004

arg int nextDay: Jan 02 00:00:00 CST 2004

d2 agter nextDay: Jan 01 00:00:00 CST 2004

这个实例可能让你看起来有点迷惑。有人会说如果java是pass by value的话,d1 after nextDay:应该为Jan 01 00:00:00 CST 2004才对!错!Java中的对象是object reference。事实上,nextDateReplace()是在与『Date对象(d2)的reference的复件』打交道,而不是与『Date对象(d2)的复件』打交道。在进入nextDateUpdate(Date arg)之时,这个对象看起来象这样:

聪明的你这下应该明白了吧!如果还没明白!没关系,再来一个更详细的例子:

清单三:

import java.awt.Point;

class Param {

public static void main (String[] args) {

Point p = new Point(0,0); //1

int i = 10;

System.out.println ("Before modifyPoint: " + "p = " + p +

" and i = " + i);

modifyPoint (p,i); //2

System.out.println ("After modifyPoint: " + "p = " + p +

" and i = " + i);

}

private static void modifyPoint (Point pt , int j) {

pt.setLocation (5,5); //3

j = 15;

System.out.println ("During modifyPoint: " + "pt = " + pt +

" and j = " + j);

}

}

会产生这样的输出:

Before modifyPoint: p = java.awt.Point[x=0,y=0] and i = 10

During modifyPoint: pt = java.awt.Point[x=5,y=5] and j = 15

After modifyPoint: p = java.awt.Point[x=5,y=5] and i = 10

这段代码在//1处建立了一个Point对象并设初值为(0,0),接着将其值赋予Object reference变量p。然后对基本型别int I赋予数值10。//2调用static modifyPoint(),传入p和i。modifyPoint()对第一个参数pt调用了setLocation(),将其坐标改为(5,5)。然后将第二个参数j赋值为15。当modifyPoint()返回的时候,main()打印出p和i的值。

根据程序输出,modifyPoint()改变了//1所建立的Point对象,却没有改变int i。在main()之中,i被赋值为10。由于参数通过by value方式传递,所以modifyPoint()收到i的一个副本,然后它将这个副本改为15并返回。main()内的原值i并没有受到影响。

对比之下,你或许认为//1建立的point对象也没有被modifyPoint()修改。毕竟Java是pass by value方式来传递参数。于是乎,当调用modifyPoint()并传入//1所建立的point对象时,就会产生一个复件配合modifyPoint()工作。modifyPoint()之中对于point对象所做的修改不会反映到main()中,因为它们是两个不同的对象嘛。对不对?错!

事实上modifyPoint()是在与是在与『point对象的reference的复件』打交道,而不是与『point对象的复件』打交道。你知道的,p是个object reference,并且Java是pass by vlaue方式传递参数。更明确的说,Java是以by value方式传递object reference。当p从main()被传入modifyPoint()时传递的是p(也就是一个reference)的复件。所以modifyPoint()是在与同一个对象打交道,只不过通过别名pt罢了。在进入modifyPoint()之后和执行//3之前,这个对象看起来象这样:

所以//3执行过后,这个point对象已经改变为(5,5)。

结语:通过上面说的,Java是pass by value方式传递参数的。当然就算你已知道java是pass by value方式传递参数的,它有时也会让你感到迷糊。从本质上说,object reference是按值传递的(pass by value),因此我们能够修改参数对象的内部状态。我们应该采用《重构》中的‘Remove Assignments to Parameters’进行重构,以此来避免可能发生的问题。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有