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 変数は、多くても 1 回代入する必要があります。割り当てが発生したときは、確実に割り当てを解除する必要があります。このような代入は、変数の単純名 (またはフィールドの場合は、これによって修飾された単純名) が代入演算子の左側にある場合にのみ発生するように定義されています。[ §16 ]

これは、静的な最終変数を割り当てるときに「単純な名前」を使用する必要があることを意味します。つまり、修飾子のない var 名です。

于 2012-12-08T15:05:27.830 に答える
7

どうやらこれは、クラス自体の中で明確な(非)割り当て分析を制限するための安価な構文上のトリックです。

フィールドが構文的にクラス名で修飾されている場合、コードは通常、分析が到達できない別のクラスにあります。

このトリックはあなたの例では失敗します。奇妙な他の例:

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

彼らがより多くのリソースを持っていれば、彼らはおそらくより細かいルールを作ったでしょう。ただし、現在、仕様を変更することはできません。

于 2012-12-08T17:51:50.053 に答える