53

情况1

class Program {
    static final int var;

    static {
        Program.var = 8;  // Compilation error
    }

    public static void main(String[] args) {
        int i;
        i = Program.var;
        System.out.println(Program.var);
    }
}

案例2

class Program {
    static final int var;

    static {
        var = 8;  //OK
    }

    public static void main(String[] args) {
        System.out.println(Program.var);
    }
}

为什么情况 1会导致编译错误?

4

2 回答 2

43

JLS 给出了答案(注意粗体声明):

同样,每个空白的 final 变量最多只能赋值一次;当对它进行分配时,它必须绝对未分配。当且仅当变量的简单名称(或者,对于字段,其简单名称由此限定)出现在赋值运算符的左侧时,才定义这样的赋值。[ §16 ]

这意味着在分配静态最终变量时必须使用“简单名称” - 即没有任何限定符的 var 名称。

于 2012-12-08T15:05:27.830 回答
7

Apparently this is a cheap syntactic trick to limit definite (un)assignment analysis within the class itself.

If the field is syntactically qualified with a class name, the code is usually in another class, where the analysis cannot reach.

This trick fails in your example. Other examples of oddity:

static class A
{
    static final int a;
    static
    {
        // System.out.println(a); // illegal
        System.out.println(A.a);  // compiles!
        a = 1;
    }
}

If they had more resources, they probably would've made a finer rule. But we can't change spec now.

于 2012-12-08T17:51:50.053 回答