notbrainsurgery ([info]notbrainsurgery) wrote,
@ 2003-12-15 23:20:00
Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Entry tags:java

definite assignment in Java
Let us consider the following code:

class x
{
    x()
    {
        int i;

        try
        {
            i=1;
            e();
        } catch(java.io.IOException ex)
        {
            System.err.println("i="+i);
        }
    }

    void e() throws java.io.IOException {}
}


When compiled, it triggers following compilation error:


x.java:13: variable i might not have been initialized
            System.err.println("i="+i);
                                    ^
1 error


It seems to be bogus, since checked exception java.io.IOException could not possibly happen any point of execution before the call to method "e", and nothing seems to prevent 'i' from being assigned in the first statement of the 'try' block.

However, the error message, though contradicting common sense, is perfectly in compliance with Java Languages Specification, which
states: "A Java compiler must carry out a specific conservative flow analysis to make sure that, for every access of a local variable or blank final field f, f is definitely assigned before the access; otherwise a compile-time error must occur."

And little further:

These rules apply to every try statement, whether or not it has a finally block:

* V is [un]assigned before the try block iff V is [un]assigned before the try statement.
* V is definitely assigned before a catch block iff V is definitely assigned before the try block.
* V is definitely unassigned before a catch block iff V is definitely unassigned after the try block and V is definitely unassigned before every return statement that belongs to the try block, every throw statement that belongs to the try block, every break statement that belongs to the try block and whose break target contains (or is) the try statement, and every continue statement that belongs to the try block and whose continue target contains the try statement.

If a try statement does not have a finally block, then this rule also applies:

* V is [un]assigned after the try statement iff V is [un]assigned after the try block and V is [un]assigned after every catch block in the try statement.


I think flow control analysis rules for 'try' statement need to be refined a bit in further editions of JLS.



(Post a new comment)

What for?
[info]trivee
2003-12-15 11:41 pm UTC (link)
The key word here is conservative flow analysis. I don't think the false positive in your example is such a big deal.

Nice interview question, though :)

(Reply to this) (Thread)

Re: What for?
[info]vzaliva
2003-12-16 12:00 pm UTC (link)
It would not be big a deal, if it would not produce compilation ERROR (not warning!) which prevents code from being compiled.

(Reply to this) (Parent)


Create an Account
Forgot your login or password?
Login w/ OpenID
English • Español • Deutsch • Русский…