5

Eclipseが「ローカル変数が初期化されていない可能性があります」というエラーを報告する方法に奇妙な二分法を発見しました。このエラーは通常、変数をtry / catchブロックの外側で宣言し、それをtry / catchブロックの内側で初期化し、try/catchブロックの後で使用すると発生します。

Random r;
try {
    r = new AESCounterRNG();
} catch (GeneralSecurityException e) {
    e.printStackTrace();
}
r.nextInt(); //Error: The local variable r may not have been initialized

意味あり。変数nullを宣言するときに初期化する、try / catchブロック内で例外が発生した場合にプログラムの制御フローが次のステートメントに到達しないようにすることで、エラーを回避できます。したがって、変数の初期化が失敗した場合に実際に実行を続行できない場合は、次のようにすることができます。

Random r;
try {
    r = new AESCounterRNG();
} catch (GeneralSecurityException e) {
    throw new RuntimeException("Initialize secure random number generator failed");
}
r.nextInt(); //No error here

ただし、最近、プログラムのコンソール出力をよりクリーンにするために、System.exitの代わりにを使用してプログラムを停止しようとしました。RuntimeExceptionどちらもプログラムの実行を継続できないため、これらは同等だと思いますが、Eclipseが同意しないことを発見しました。

Random r;
try {
    r = new AESCounterRNG();
} catch (GeneralSecurityException e) {
    System.err.println("Couldn't initialize secure random number generator");
    System.exit(1);
}
r.nextInt(); //Error: The local variable r may not have been initialized

r.nextInt()例外が発生した場合に実行に到達できないのに、Eclipseで「初期化されていません」エラーが発生するのはなぜですか?これはEclipseのバグですか、それともr.nextInt()呼び出した後も実行を継続できる方法はありSystem.exitますか?

4

2 に答える 2

5

良い質問です。何度か私を悩ませました。

問題は、例外をスローする場合とは異なり、メソッドを呼び出すだけでは (それが実際System.exit(1);にそうです)、通常、プログラム フローの停止が保証されないことです。確かに、System.exit() のドキュメントには、このメソッドが正常に戻ることはないと書かれています。しかし、 のセマンティクスはthrow言語自体によって定義されていますが、 のセマンティクスはSystem.exit()Javadoc にあるだけです。

私の推測では、彼らはこの特殊なケースをまだ実装しようとはしていませんでした。このトピックに触れたバグレポートがありますが ( https://bugs.eclipse.org/bugs/show_bug.cgi?id=126551、コメント 2 を参照)、「修正しない」とマークされています。複雑すぎる。

編集: rlegendi が指摘したように、実際には Eclipse だけでなく Java コンパイラの問題です。これまでの私の解決策は、(非常に小さなアプリケーション以外では)とにかく優れている(throw特別なメソッドの代わりに)単純な古い , を使用することでした。throw()System.exit()

于 2012-09-22T18:40:01.243 に答える
1

これはバグではありません: 2 番目の例では、呼び出しサイトで初期化されることが保証されていrます (それ以外の場合は例外をスローして、実行ブランチが閉じられるようにします)。

最初と 3 番目の例では、単にプログラム コードを実行し、r未定義のままにしています。null例外処理ブロックまたは宣言で割り当てても、文句はありません。

ところで、これは Eclipse の問題ではありません。JLS によって、初期化されていない変数を使用できないことが定義されています。Java でコンパイルしてみてください。まったく同じ出力が得られるはずです。

于 2012-09-22T18:28:03.973 に答える