Community
Participate
Working Groups
public class Hello() { public static void main(String[] args) { int x, y; x = y = 0; List list; if (x == y) { list= new ArrayList(1); list.add("Graah!"); } System.out.println("Foo"); } } 1. Place a breakpoint on line 5 ("x = y = 0") and begin stepping. 2. Note that "list" appears in the variables view when it is initialized inside the "if" statement. 3. Note that "list" disappears from the variables view when you step out of the "if" statement. Changing the conditional expression to "true" or adding an unconditional "else" after the "if" makes the list variable persist. NOTES: JMB (10/10/2001 3:34:19 PM) Note that this may be a compiler bug. I checked my compiler preferences and the preference "Preserve unused local variables" is selected, so the compiler should not be removing "list". DW (10/10/2001 3:59:47 PM) I debugged, and noted that the variables view was displaying correct relative to what we get back from (jdi) StackFrame.visibleVariables(). The "list" variable appears and disappears from the visible variable list. Moved to JCORE - suspect this is a compiler issue.
Please investigate
This is not a bug. If you look at the code source: import java.util.List; import java.util.ArrayList; public class Hello { public static void main(String[] args) { int x, y; x = y = 0; List list; if (x == y) { list= new ArrayList(1); list.add("Graah!"); } System.out.println("Foo"); } } If the if condition is false, then the list variable is not initialized and so it has no reason of being displayed outside of the if statement. In compiler term, the list variable is *not* definitely assigned after the if statement and this is why it has been removed from the list of visible variables. If you write a code that uses list without initializing it, you would run into a error: "The local variable list may not have been initialized". For example, try to compile: [import java.util.List; import java.util.ArrayList; public class Hello { public static void main(String[] args) { int x, y; x = y = 0; List list; if (x == y) { list= new ArrayList(1); list.add("Graah!"); } System.out.println("Foo" + list); } }] The ranges in the local variable attributes are only ranges when the local is actually initialized and *not* when it is defined. I agree that list is defined after the if statement, but it may not have been initialized. This is consistent with the VM specs. The VM specs state: "Each entry in the local_variable_table array indicates a range of code array offsets within a local variable has a value." In this case the variable list has no value if the if condition is false. Therefore we close the range. Surprisingly javac 1.3 doesn't close the range and consider list has been initialized till the end of the method. But if you compile the second piece of code, it complains that list may not have been initialized. I don't find this behavior very consistent.
Need more investigation What happens then if debugging the following file, and put a breakpoint on the line with comment /// look at #list value. If the file was compiled with Eclipse, then #list would not be available, but if compiled with Sun, what happens since the variable has no value ? import java.util.List; import java.util.ArrayList; public class Hello { public static void main(String[] args) { int x, y; x = y = 0; List list; if (x != y) { list= new ArrayList(1); list.add("Graah!"); } System.out.println("Foo"); /// look at #list value } }
Javac 1.2.2 has the same ranges we do. Javac 1.3 and 1.4 don't. I suspect a bug, because we follow the specs. Now it is possible they decided to change this behavior, but the latest JLS and VM specs don't reflect it. I would say that our behavior can easily be explained, because we display a variable only when the variable is definitely assigned and not when it is potentially assigned. Using a .class file compiled with javac 1.3, I could see the value of the local list after the if statement in the debugger. It works fine. But I am sure that we can have problems in some patterns. As long as it is not possible to use a variable, I don't see why we would display its value. So I would close this PR. If it is really annoying for users, we might want to change our behavior, but then it is more difficult to explain why we display a variable which is not *definitely* assigned. Matching the specs should not be considered as a bug.
Move to closed.
PRODUCT VERSION: 2.0 stream