package test;/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: </p>
* @author unascribed
* @version 1.0
*/public class RangeTest { public RangeTest() {} public String getStr(){
String str = new String("adfalkjjfa");
return str;
}
public static void main(String[] args) {
try {
RangeTest rangeTest1 = new RangeTest();
String str = rangeTest1.getStr();
System.runFinalization();
str = rangeTest1.getStr();
rangeTest1.finalize();
// rangeTest1 = null;
System.out.println(" getStr is : "+str);
}
catch (Throwable ex) {
ex.printStackTrace();
}
}
}
//都不行,天啦,没有天理啊。
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: </p>
* @author unascribed
* @version 1.0
*/public class RangeTest { public RangeTest() {} public String getStr(){
String str = new String("adfalkjjfa");
return str;
}
public static void main(String[] args) {
try {
RangeTest rangeTest1 = new RangeTest();
String str = rangeTest1.getStr();
System.runFinalization();
str = rangeTest1.getStr();
rangeTest1.finalize();
// rangeTest1 = null;
System.out.println(" getStr is : "+str);
}
catch (Throwable ex) {
ex.printStackTrace();
}
}
}
//都不行,天啦,没有天理啊。
String tmp = test.getStr();相当于 tmp = str;
当然会输出asdklajs;di了!
是关闭了rangeTest1这个对象吧!
str仍然有值啊!
那这个程序该怎么写————体现出堆栈的关闭。我的理解是无论tmp还是str,都是对一个内存地址的引用,当相应的堆栈关闭以后,应该内存被回收的。
请问你用的JAVA还是C++?不如描述你要解决的问题,看大家能不能帮你吧。在JAVA中,只要存在引用,对象不会被作为垃圾收集掉的。
也就是说,无论java还是c++,我的getStr()都不应该返回能够预料到的结果。
我想这是一个关系到变量生命周期的问题,每个人都会被问到过若干回。回答无一例外的是getStr()的返回值不值得信赖——我记得林锐写的那本书上就是这么说的。但是事实结果并不是这样。
这个是干什么用呢?
对象只能通过引用来使用,只有无法通过任何路径访问到的对象才被垃圾收集!
譬如:
Java中单链表的释放非常简单,只要把表头引用赋值为null即可: head = null;
这样后续节点不管有多少,由于没有任何办法访问到,都会被垃圾收集。(不过我试了一下,当链表长度超过一定大小时,sun的JVM似乎就很难成功的垃圾收集之,这与垃圾收集机制有关系)
不知道除了使用堆栈,还有没有别的方式——好像是没有。当栈顶的数据被弹出以后,如果被弹出的数据地址不被清空应该说是jvm设计上的一个bug不是吗?
public String getStr(){
String str = new String("adfalkjjfa");
return str;
}
该方法中,对象"adfalkjjfa"放在堆里,它的引用str放在栈里。
该方法退出时,栈里的str被释放,对象"adfalkjjfa"依然在堆里。但是由于该方法有返回值,return str;所以将str的值拷贝一份返回(值传递,该值是对象"adfalkjjfa"在堆里的地址)。所以该方法并不是返回了局部变量(它的生命周期已过),而是返回了该局部变量的一份拷贝,依然是指向对象"adfalkjjfa"的一个引用。
String str = new String("adfalkjjfa");
return str+"123";
}结果还是一样。package test;public class ScopeTest{ public StringBuffer getStr(){
StringBuffer buf = new StringBuffer("asdmonster");
return buf;
} public static void main(String[] args){
ScopeTest test = new ScopeTest();
StringBuffer tmp = test.getStr();
System.out.println(" getStr return : "+tmp);
}
}结果还是一样。
TEM从GETSTR()中得到字符串,他又没被消除当然还在
public String getStr(){
String str = new String("asdklajs;di");
return str;
} public static void main(String[] args){
ScopeTest test = new ScopeTest();
String tmp = test.getStr();
System.out.println(" getStr return : "+tmp);
System.runFinalization();
tmp = test.getStr();
System.out.println(" getStr return : "+tmp);
}
}好像你在做無用功呀!
getStr裏面
String str = new String("asdklajs;di");
每次調用這個方法Str都被賦給了一個新的引用!
System.runFinalization();根本對你的結果不會有影響。
首先不談垃圾收集是怎麽收集的,你每次都給str一個新的對象,Java要回收也只是會收上一個對象的並不是回收str。就算是回收str,你調用String str 又重新定義了這個變量,所以根本就不能證明什麽!
public String getStr(){
String str = new String("adfalkjjfa");
return str;
}
和
public String getStr(){
String str = new String("adfalkjjfa");
return str+"123";
}
这两个方法有区别吗?
他们都等价于:
public String getStr(){
return <java.lang.String>;
}
看来是没有认真看我上面的回复哎~
System.runFinalization();
垃圾回收只会回收没有任何引用的对象,tmp仍有引用,当然存在。要是没有引用你怎能print出来?
再者,System.runFinalization()只是建议垃圾回收工作,而不是强迫垃圾回收工作。java的垃圾回收机制是不能被控制的。你在钻牛角尖。
但是在调用方法时有这么一个过程,产生str,对str赋值,然后str把值赋给temp
,这个时候方法调用结束,而str也就不存在了,之后和str也就没有关系了至于第二个例子,由于楼主用了同样的变量名,容易混淆,其实这时候两个str是不一样的