I can see this curious behaviour from the garbage collector
public class A {
public static void main(String[] args) {
String foo;
try {
foo = "bar";
int yoo = 5; //1
} catch (Exception e) {
}
int foobar = 3;//2
}
}
if I go to debug and put a breakpoint on //1 foo is not null and its value is “bar” but in breakpoint //2 foo is null, this can be difficult to understand while you are debug. My question is if there is any specification that says that this is a legal behaviour from the garbage collector
With this small variation it doesn’t get Garbage collected:
public class A {
public static void main(String[] args) {
String foo;
try {
foo = "bar";
} catch (Exception e) {
throw new RuntimeException(e);
}
int foobar = 3;
}
}
Why?
In this case, you don’t use the foo variable after setting it, so it would even be legal for the JVM to completely ignore the variable as it is never used and that would not change the result of your program.
However that’s unlikely to happen in debug mode.
In your case, foo should not get GC’ed as long as it is in scope or you hold a reference to it, which includes the section after the try/catch block.
EDIT
Actually I get the same behaviour as what you describe in Netbeans 7.1.1 with Java 7.0_03…
One problem might be that because you don’t set a default value to
foo, you can’t use it after the try/catch block (it would not compile).Bytcode
String foo = null;as the first statement, in which case the debugger see the value after the try/catch block:I’m not a bytcode specialist but they look very similar to me…
CONCLUSION
My personal conclusion is that for the debugger to show the value of
foo, it has to run afoo.toString()of some sort, which is not a valid statement after the catch block asfoomight have not been initialized. Adding aSystem.out.println(foo)in that section is not legal (does not compile). The debugger is a bit lost as to what the value is and showsnull.To convince yourself that this has nothing to do with GC, you can try the following example:
On the
foobarline, you can see thatcholdsbarbut foo shows asnull. So the String is still there, but the debugger can’t show it.Even funnier example:
On the
foobarline,fooshows asnull, butlistcontains"bar"… Nice.