|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
- 发信人: javarookie (布猫), 信区: Java
- 标 题: Re: 关于传地址的一点疑问,请教!
- 发信站: BBS 水木清华站 (Sun Oct 13 22:51:17 2002), 站内信件
- 稍微修改一下程序就可以使你明了程序的运行过程:
- class ValHold {
- public int i = 10;
- }
- public class ObParm {
- public void amethod() {
- ValHold v = new ValHold();
- another(v);
- System.out.println(v.i + "a"); //(*)
- // ~~~~~~加上一个标识 a
- }
- public void another(ValHold v) {
- v.i = 20;
- ValHold vh = new ValHold();
- v = vh;
- System.out.println(v.i + "b");
- // ~~~~~~加上一个标识 b
- }
- public static void main(String[] argv) {
- ObParm o = new ObParm();
- o.amethod();
- }
- }
- 程序运行结果:
- 10b
- 20a
- 这是怎么回事呢?
- 一定要分清变量!
- 在头脑中从头开始运行程序,并把全过程写下来,就很清楚了:
- main() --> 创建 o --> 运行 o.amethod() --> 创建 v (amethod.v) --> amethod.v
- 引用新的 ValHold 对象 --> 调用 another(v) --> 创建 another.v --> another.v
- 引用 v 指向的对象(此时内存中存在一个 amethod.v 和一个 another.v,他们均引用
- ValHold 的同一个对象)-->another.v.i 赋值 20,由于amethod.v 和 another.v 引
- 用同一个对象,因此此时的 v 和 another.v 引用的 ValHold 对象的 i 值被更改为20
- --> 创建 another.vh --> another.vh 引用一个新 ValHold 对象 --> another.v 的
- 引用改为 vh 引用 --> 输出 another.v.i,此时的 another.v 引用 vh 引用的对象,
- 因此 i = 10 --> 退出 another 方法,another.v 作为局部变量也将被抛弃 -->
- 回到 amethod 方法 --> 输出 v 的 i 值,此时为 20 --> 退出程序,并调用gc(),
- 回收原来 v 变量引用的对象和 another.vh及another.v 引用的对象
- 如果算上我加的两个字符串变量"a" 和 "b" 的话,那么还要回收他们,呵呵
- 【 在 cooldie (蝶·一笑而过) 的大作中提到: 】
- : 此题的答案是
- : 10
- : 20
- : 为什么不是
- : 10
- : 10呢?
- : class ValHold{
- : public int i = 10;
- : }
- : public class ObParm{
- : public void amethod(){
- : ...................
- 发信人: JoyJava (it's a yellow lemon tree ...), 信区: Java
- 标 题: Re: 关于传地址的一点疑问,请教!
- 发信站: BBS 水木清华站 (Mon Oct 14 14:37:11 2002), 站内信件
- 这个问题还在争论?分特。。。。。。我画蛇添足一把:
- 定义类的实例a和b,这是指内存中的表现。三个我们自己的变量v1,v2,v3。
- v1->a,v2->b,当我们定义v3->a的时候,说明v1,v3->a,但是当我们让
- v3->b的时候,并不是a-->b,而仅仅是v3,也就是说,这个操作不能改变
- v1也同时指向b。
- 后来想了一下,这个问题和传参的关系不大,而是引用和实例的概念理解
- 有误。
- 【 在 javarookie (布猫) 的大作中提到: 】
- : 不知道你从哪儿看的!
- : 我个人认为所述极端不正确!
- : 你应该参考 Sun 公司的 SCJP 官方教材 SL-275
- : 我个人认为张洪斌老师对这个的理解不正确(就是你括号里那段)
- : 此 v 非彼 v,而是两个不同的引用,虽然名称相同,但是有不同的scope
- : 一个属于 amethod()方法,另外一个属于 another() 方法,因此在内存中是两个
- : 不同的变量,只不过引用同一个对象而已,因此不存在所谓的:
- : “v又回复到第一次ValHold v = new ValHold();时指向的地址空间”,
- : 因为这个引用从未被改变过,所以谈不上什么回复
- : 不知道是你的理解错误,还是张老师的理解错误
- : 我去信问问,你也写封信问问吧
- 发信人: cooldie (蝶·一笑而过), 信区: Java
- 标 题: Re: 关于传地址的一点疑问,请教!
- 发信站: BBS 水木清华站 (Mon Oct 14 09:49:07 2002), 站内信件
- 这样解释吧,按照sun官方的说法:当一个引用变量作为参数传递给一个方法时,
- 在这个方法内可以改变变量的值,即改变引用指向的对象,(本题中将vh赋给v)
- 但是方法的调用结束后,改变量恢复原来的值,即变量仍然指向原来的对象。
- (即another(v)调用结束之后,v又回复到第一次ValHold v = new ValHold();时
- 指向的地址空间。)
- 但是如果在方法内改变了引用指向的对象的数据(属性),那么当方法的调用结束
- 后,尽管引用仍然指向原来的对象,这个对象的某个属性已经被改变了(v的i值在
- 执行v.i=20的时候就已经被改变了,所以调用another结束后,v.i已经变成了20)
- //括号中的文字是本题的实际情况,其他文字是对引用变量作为参数传递时的原理
- //这段话来自张洪斌的《成功通过sun认证Java2程序员考试》
- 【 在 cooldie (蝶·一笑而过) 的大作中提到: 】
- : 此题的答案是
- : 10
- : 20
- : 为什么不是
- : 10
- : 10呢?
- : class ValHold{
- : public int i = 10;
- : }
- : public class ObParm{
- : public void amethod(){
- : ...................
- 发信人: javarookie (布猫), 信区: Java
- 标 题: Re: 关于传地址的一点疑问,请教!
- 发信站: BBS 水木清华站 (Mon Oct 14 14:22:46 2002), 站内信件
- 不知道你从哪儿看的!
- 我个人认为所述极端不正确!
- 你应该参考 Sun 公司的 SCJP 官方教材 SL-275
- 我个人认为张洪斌老师对这个的理解不正确(就是你括号里那段)
- 此 v 非彼 v,而是两个不同的引用,虽然名称相同,但是有不同的scope
- 一个属于 amethod()方法,另外一个属于 another() 方法,因此在内存中是两个
- 不同的变量,只不过引用同一个对象而已,因此不存在所谓的:
- “v又回复到第一次ValHold v = new ValHold();时指向的地址空间”,
- 因为这个引用从未被改变过,所以谈不上什么回复
- 不知道是你的理解错误,还是张老师的理解错误
- 我去信问问,你也写封信问问吧
- 张洪斌老师的邮件地址:
- mailto:bestbooks@netease.com
- (张老师比较喜欢吹牛,他的话不可全信,呵呵)
- 当然不排除本人理解错误,大家请指正
- 补充一句,《成功通过SUN认证 Java2 程序员考试》是张老师自己写的,
- 不代表 SUN 的“官方的说法”
- : 这样解释吧,按照sun官方的说法:当一个引用变量作为参数传递给一个方法时,
- : 在这个方法内可以改变变量的值,即改变引用指向的对象,(本题中将vh赋给v)
- : 但是方法的调用结束后,改变量恢复原来的值,即变量仍然指向原来的对象。
- : (即another(v)调用结束之后,v又回复到第一次ValHold v = new ValHold();时
- : 指向的地址空间。)
- : 但是如果在方法内改变了引用指向的对象的数据(属性),那么当方法的调用结束
- : 后,尽管引用仍然指向原来的对象,这个对象的某个属性已经被改变了(v的i值在
- : 执行v.i=20的时候就已经被改变了,所以调用another结束后,v.i已经变成了20)
- : //括号中的文字是本题的实际情况,其他文字是对引用变量作为参数传递时的原理
- : //这段话来自张洪斌的《成功通过sun认证Java2程序员考试》
复制代码 |
|