ljnelson noted at 'http://weblogs.java.net/blog/jst/archive/2008/10/the_better_comp.html' that it is enough to make the variable final and the problem goes away. True, final helps, however the same code without final works as well. This very likely means that the compiler puts the variable into the topmost block where it is guaranteed to be fully initialized. That is why we need a hint warn about declaration of non-fully initialized variables.
1.1 --- a/samples/gc/test/org/apidesign/gc/CompilerSurprisesTest.java Wed Oct 15 21:48:18 2008 +0200
1.2 +++ b/samples/gc/test/org/apidesign/gc/CompilerSurprisesTest.java Fri Oct 17 09:01:08 2008 +0200
1.3 @@ -61,6 +61,31 @@
1.4 }
1.5 // END: compiler.surprises.fix
1.6
1.7 +// BEGIN: compiler.surprises.fix.init
1.8 + @Test public void properInitializationFixesTheProblem() {
1.9 + String retValue;
1.10 + if (yes) {
1.11 + retValue = factory();
1.12 + } else {
1.13 + retValue = null;
1.14 + }
1.15 + assertNotGC("Cannot be GCed, now the retValue is on stack", cache);
1.16 + }
1.17 +// END: compiler.surprises.fix.init
1.18 +
1.19 +// BEGIN: compiler.surprises.fix.final
1.20 + @Test public void properUsingFinalFixesTheProblem() {
1.21 + final String retValue;
1.22 + if (yes) {
1.23 + retValue = factory();
1.24 + } else {
1.25 + retValue = null;
1.26 + }
1.27 + assertNotGC("Cannot be GCed, now the retValue is on stack", cache);
1.28 + }
1.29 +// END: compiler.surprises.fix.final
1.30 +
1.31 +
1.32 private static void assertGC(String msg, Reference<?> ref) {
1.33 NbTestCase.assertGC(msg, ref);
1.34 }