Why attempt to print uninitialized variable does not always result in an error message

前端 未结 6 1871
滥情空心
滥情空心 2020-12-24 10:28

Some may find it similar to the SO question Will Java Final variables have default values? but that answer doesn\'t completely solve this, as that question doesn\'t directl

6条回答
  •  感动是毒
    2020-12-24 11:26

    Reading the JLS, the answer appears to be in section 16.2.2:

    A blank final member field V is definitely assigned (and moreover is not definitely unassigned) before the block (§14.2) that is the body of any method in the scope of V and before the declaration of any class declared within the scope of V.

    This means that when a method is called, the final field is assigned to its default value 0 before invoking it, so when you reference it inside the method, it compiles successfully and prints the value 0.

    However, when you access the field outside of a method, it is considered unassigned, hence the compilation error. The following code will also not compile:

    public class Main {
        final int x;
        {
            method();
            System.out.println(x);
            x = 7;
        }
        void method() { }
        public static void main(String[] args) { }
    }
    

    because:

    • V is [un]assigned before any other statement S of the block iff V is [un]assigned after the statement immediately preceding S in the block.

    Since the final field x is unassigned before the method invocation, it is still unassigned after it.

    This note in the JLS is also relevant:

    Note that there are no rules that would allow us to conclude that V is definitely unassigned before the block that is the body of any constructor, method, instance initializer, or static initializer declared in C. We can informally conclude that V is not definitely unassigned before the block that is the body of any constructor, method, instance initializer, or static initializer declared in C, but there is no need for such a rule to be stated explicitly.

提交回复
热议问题