1
public class Test1 {
    static final int i;
    static{
        if(3<2){
        i = 0;
        }
    }   
}
public class Test2 {
    static final int i;
    static{
        if(3>2){
        i = 0;
        }
    }   
}

クラスTest1のコンパイルに失敗しました。クラスTest2は正常にコンパイルされました。

if 条件でコンパイラがどのように式を評価できるか教えてもらえますか?

4

4 に答える 4

5
static final int i;

最終的なものであるため、静的初期化子で初期化する必要があります。

static{
        if(3<2){
        i = 0;
        }
    }

3<2 リテラルまたは定数のため、コンパイラはコードのデッド部分を検出でき、i を初期化できませんでした。

elseケースを追加し、iそこで初期化を行います。

于 2012-12-09T10:00:33.690 に答える
2

これは、コンパイラがステートメントを実行するかどうかを決定する方法に関係しています。JLS #16で定義されています。

各ローカル変数とすべての空白の最終フィールドには、その値へのアクセスが発生したときに、確実に値が割り当てられている必要があります。

あなたの例では、コンパイラは、 の式が定数式iであるため、コンパイル時に確実に割り当てられている (または割り当てられていない) と判断できます。if

JLS #15.28定数式を定義しています:

コンパイル時の定数式は、プリミティブ型の値を示す式、または突然完了しない String であり、以下のみを使用して構成されます。

  • プリミティブ型のリテラル [...]
  • 関係演算子 <、<=、>、および >= [...]

興味深いことに、Test2 はコンパイルされますが、この変更されたバージョンの Test2 はコンパイルされません。

static class Test3 {
    static final int i;
    static {
        int j = 3;
        if (j > 2) {
            i = 0;
        }
    }
}

その理由は、それj > 2がもはや定数式ではないからです。jfinalを作成すると、クラスが再度コンパイルされます。

于 2012-12-09T10:06:27.803 に答える
2

Java 言語仕様によると、if ステートメントの条件部分の式はコンパイル時の式です。Test1 では、コンパイラは i が初期化されないことを知っているため、不平を言います。2 番目のケースでは、コンパイラは i が初期化されることを認識しています。コンパイル時の式をより動的なものに置き換えると、コンパイラは i が初期化されていることを保証できないため、両方のクラスがコンパイルに失敗します。

于 2012-12-09T10:08:49.440 に答える
0

if (3<2)に最適化できるif (false)ため、Java コンパイルは到達不能ステートメント (エラー) を検出します。

if (3>2)に最適化できif (true)、囲まれたステートメントは常に実行されます。それで問題ありません。

コンパイラは、これらが定数スカラーであることを簡単に検出できるため、コンパイル時に式を評価 (最適化) できます。まともなコンパイラには何も期待できません。

于 2012-12-09T11:15:52.643 に答える