Reputation: 628
I am trying to figure out the inner workings of this code.
public void method() {
int x;
try {
x = 10;
} catch(Exception e) {
throw new RuntimeException(); //commenting out this line causes error
}
System.out.println("x: " + x);
}
When I comment out line 6, I get a compilation error on line 8 that x might have not been initialized. When I keep the throw statement inside the catch block, I get no such error. How does this make any difference? The way I see it, you can either initialize a variable inside a try block and use that value outside, or you cannot. At any rate, no exceptions are actually thrown because the catch block is never entered. Surely the mere possibility of an exception being thrown isn't causing the compiler to allow what would otherwise be a violation of Java syntax, right?
Upvotes: 2
Views: 350
Reputation: 5784
I can't speak to whether there are any real exceptions that could occur within the try
– something like OutOfMemoryError
might occur, but wouldn't be caught with catch (Exception e)
– but I believe this is just due to the compiler being extra careful (perhaps unnecessarily so).
It isn't relevant that the line inside your try
block doesn't throw an exception. Instead, it's evaluating that if an exception were to be thrown inside the try
statement (somehow) and execution was subsequently allowed to continue past the catch
clause, then x
would be in an uninitialized state.
The exact answer is most likely buried in the Java Language Spec, possibly in 14.21. Unreachable Statements or 14.20.1. Execution of try-catch.
Upvotes: 2
Reputation: 1789
Looking at the simple code:
int x;
System.out.println(x);
The compiler detects that variable x
may not have been initialized at the point where it is referenced, so it throws a compile error.
Now looking at your example, there are two paths the compiler can be sure about that code can take: Execute the try block or execute the catch block (with the latter, partial execution of the try block is possible as well). In this second case, the x
variable will not be initialized and the compiler cannot generate sensible bytecode instructions. However, with the throws
in the catch block, the execution of this code will stop and the usage of x
is never reached, solving the uninitialized variable problem for the compiler.
To include another example that might be easier to understand:
int x;
if(someCondition()) {
x = 1;
} else {
// x is not initialized through this code path.
}
System.out.println(x); // x may be initialized here, but it is not guaranteed, so this causes a compile error.
Upvotes: 1