当前位置: 技术问答>java相关
关于“传地址”和“回收”的问题:
来源: 互联网 发布时间:2017-04-18
本文导语: class ValHold { public int i = 10; } public class ObParm { public void amethod() { ValHold v = new ValHold(); another(v); System.out.println(v.i + "a"); //(*) ...
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
我的问题是这样的:
1.在anther中,v=vh以后,ObParm 中的v、anther中的v和vh,这三个是否都指向一个对象?
2.anther中的v在anther结束以后,是否被回收?
如果没有,那末它的reference指向哪里?
谢谢各位
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
我的问题是这样的:
1.在anther中,v=vh以后,ObParm 中的v、anther中的v和vh,这三个是否都指向一个对象?
2.anther中的v在anther结束以后,是否被回收?
如果没有,那末它的reference指向哪里?
谢谢各位
|
楼主 没搞清楚object和object reference的关系。
比如楼主问anther中的v在anther结束以后,是否被回收? 和anther中的vh在被回收后,anther中的v指向哪里呢? 这样提问是不妥的,其实被回收的是object不是object reference。
偶下面把这个程序给楼主解释一下:
ValHold v = new ValHold(); 建立了一个object(暂且叫作ValHoldA)和指向这个object的引用v(暂且叫作amethod.v)。显然ValHoldA是一个object,amethod.v是一个object reference(可以简单理解为对象的地址而不是对象本身),他们是不同的,又是有联系的。
object reference object
__________
| ValHoldA |
|----------|
amethod.v ------->| i = 10 | ValHold v = new ValHold();
|__________|
another(v); 调用了方法another(),传入的参数是amethod.v的一个copy实际上是建立了一个新的object reference,并且也指向ValHoldA。注意由于java在传递参数时,使用的是reference而不是object本身,此时并没有新的object的copy产生。
__________
| ValHoldA |
amethod.v ------->|----------| another(v);
another.v ------->| i = 10 |
|__________|
v.i = 20; 修改了对象ValHoldA的变量i为20,并未改变引用与对象之间的关系 如下:
__________
| ValHoldA |
amethod.v ------->|----------| v.i = 20;
another.v ------->| i = 20 |
|__________|
ValHold vh = new ValHold(); 建立了一个新的object(暂且叫作ValHoldB)和指向这个object的引用vh。 于是就有了两个ValHold object和三个分别指向它们的object reference。 如下:
__________
| ValHoldA |
amethod.v ------->|----------|
another.v ------->| i = 20 |
|__________|
__________
| ValHoldB |
|----------| ValHold vh = new ValHold();
another.vh------->| i = 10 |
|__________|
v = vh; 这是object reference之间的赋值,不是object之间的赋值。改变了引用与对象之间的关系,如下:
__________
| ValHoldA |
|----------|
amethod.v ------->| i = 20 |
|__________|
__________
| ValHoldB |
another.v ------->|----------| v = vh;
another.vh------->| i = 10 |
|__________|
如此,两个println的输出结果就显而易见了。
你的第一个问题,它们并不指向同一个对象,而是两个对象。
你的第二个问题,虽然你的提问方式是错的。 答案还是有的,another()执行结束后,another.v和another.vh都不存在了, 于是,ValHoldB就不存在指向它的引用,因而,符合回收的条件,何时回收不确定。你不能强迫GC在某个特定时间回收某个符合回收条件的对象,只能建议。
比如楼主问anther中的v在anther结束以后,是否被回收? 和anther中的vh在被回收后,anther中的v指向哪里呢? 这样提问是不妥的,其实被回收的是object不是object reference。
偶下面把这个程序给楼主解释一下:
ValHold v = new ValHold(); 建立了一个object(暂且叫作ValHoldA)和指向这个object的引用v(暂且叫作amethod.v)。显然ValHoldA是一个object,amethod.v是一个object reference(可以简单理解为对象的地址而不是对象本身),他们是不同的,又是有联系的。
object reference object
__________
| ValHoldA |
|----------|
amethod.v ------->| i = 10 | ValHold v = new ValHold();
|__________|
another(v); 调用了方法another(),传入的参数是amethod.v的一个copy实际上是建立了一个新的object reference,并且也指向ValHoldA。注意由于java在传递参数时,使用的是reference而不是object本身,此时并没有新的object的copy产生。
__________
| ValHoldA |
amethod.v ------->|----------| another(v);
another.v ------->| i = 10 |
|__________|
v.i = 20; 修改了对象ValHoldA的变量i为20,并未改变引用与对象之间的关系 如下:
__________
| ValHoldA |
amethod.v ------->|----------| v.i = 20;
another.v ------->| i = 20 |
|__________|
ValHold vh = new ValHold(); 建立了一个新的object(暂且叫作ValHoldB)和指向这个object的引用vh。 于是就有了两个ValHold object和三个分别指向它们的object reference。 如下:
__________
| ValHoldA |
amethod.v ------->|----------|
another.v ------->| i = 20 |
|__________|
__________
| ValHoldB |
|----------| ValHold vh = new ValHold();
another.vh------->| i = 10 |
|__________|
v = vh; 这是object reference之间的赋值,不是object之间的赋值。改变了引用与对象之间的关系,如下:
__________
| ValHoldA |
|----------|
amethod.v ------->| i = 20 |
|__________|
__________
| ValHoldB |
another.v ------->|----------| v = vh;
another.vh------->| i = 10 |
|__________|
如此,两个println的输出结果就显而易见了。
你的第一个问题,它们并不指向同一个对象,而是两个对象。
你的第二个问题,虽然你的提问方式是错的。 答案还是有的,another()执行结束后,another.v和another.vh都不存在了, 于是,ValHoldB就不存在指向它的引用,因而,符合回收的条件,何时回收不确定。你不能强迫GC在某个特定时间回收某个符合回收条件的对象,只能建议。
|
1)、
v = vh;之后,another中的v和vh指向同一个对象
而amethod里的v指向另外一个对象
2)、
关于回收问题,在java里,你是不需要考虑这个问题的
这个对象会不会被回收,何时被回收都是不确定的
因为在java中对象的回收是不是程序员去做的事情
而是由垃圾回收器gc来负责,当系统认为有进行垃圾回收的必要时
它会自动启动垃圾回收器
因此,你不可能知道何时垃圾回收器启动
但是你不必担心内存泄漏问题
如果你想知道的更详细,建议去看一下Think in java 2nd Edition
在第四章初始化与清除里,这个问题稍有涉及,我觉得讲得比较易懂^_^
v = vh;之后,another中的v和vh指向同一个对象
而amethod里的v指向另外一个对象
2)、
关于回收问题,在java里,你是不需要考虑这个问题的
这个对象会不会被回收,何时被回收都是不确定的
因为在java中对象的回收是不是程序员去做的事情
而是由垃圾回收器gc来负责,当系统认为有进行垃圾回收的必要时
它会自动启动垃圾回收器
因此,你不可能知道何时垃圾回收器启动
但是你不必担心内存泄漏问题
如果你想知道的更详细,建议去看一下Think in java 2nd Edition
在第四章初始化与清除里,这个问题稍有涉及,我觉得讲得比较易懂^_^