1-1-4-1-2 关于传地址的一点疑问,请教!
发信人: 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程序员考试》
页:
[1]