Java が静的初期化ブロックからチェック例外をスローできないのはなぜですか? このデザイン決定の背後にある理由は何でしたか?
8 に答える
ソースでこれらのチェック済み例外を処理することはできないためです。初期化プロセスを制御することはできず、静的{} ブロックをソースから呼び出すことはできないため、それらを try-catch で囲むことができます。
チェックされた例外によって示されるエラーを処理できないため、チェックされた例外の静的ブロックのスローを禁止することにしました。
静的ブロックは、チェック済み例外をスローしてはなりませんが、未チェック/実行時例外のスローを許可します。ただし、上記の理由によると、これらも処理できません。
要約すると、この制限により、開発者は、アプリケーションが回復できないエラーを引き起こす可能性のあるものを構築することができなくなります (または、少なくとも困難になります)。
チェックされた例外をキャッチし、チェックされていない例外として再スローすることで、この問題を回避できます。この未チェックの例外クラスは、ラッパーとしてうまく機能します: java.lang.ExceptionInInitializerError
.
サンプルコード:
protected static class _YieldCurveConfigHelperSingleton {
public static YieldCurveConfigHelper _staticInstance;
static {
try {
_staticInstance = new YieldCurveConfigHelper();
}
catch (IOException | SAXException | JAXBException e) {
throw new ExceptionInInitializerError(e);
}
}
}
次のようにする必要があります (これは有効な Java コードではありません)。
// Not a valid Java Code
static throws SomeCheckedException {
throw new SomeCheckedException();
}
しかし、あなたがそれをキャッチする場所にどのように広告を表示しますか? チェック例外にはキャッチが必要です。クラスを初期化する可能性のある (または既に初期化されているため、そうでない可能性がある) いくつかの例を想像してみてください。その複雑さに注意を向けるために、別の静的初期化子に例を入れました。
static {
try {
ClassA a = new ClassA();
Class<ClassB> clazz = Class.forName(ClassB.class);
String something = ClassC.SOME_STATIC_FIELD;
} catch (Exception oops) {
// anybody knows which type might occur?
}
}
そしてもう一つ厄介なこと -
interface MyInterface {
final static ClassA a = new ClassA();
}
ClassA にチェック済み例外をスローする静的イニシャライザーがあると想像してください。そのままにしておくとよいでしょう。
Java 言語仕様を見てください。静的イニシャライザが失敗 し、チェック例外で突然完了することができる場合、コンパイル時エラーであると述べられています。
記述したコードは静的初期化ブロックを呼び出すことができないため、checked をスローするのは役に立ちませんexceptions
。可能であれば、チェックされた例外がスローされたときに jvm は何をしますか? Runtimeexceptions
上に伝播されます。