web-dev-qa-db-ja.com

Java-静的初期化ブロックで最終変数を初期化できますか?

Java言語の私の理解に基づいて、静的変数はstatic initialization block

しかし、実際にこれを実装しようとすると(staticであるfinal変数も)、以下のスクリーンショットに示すエラーが表示されます。

https://i.stack.imgur.com/5I0am.jpg

44
Yatendra Goel

はい、もちろん:static final変数は静的ブロックで初期化できますbut ....その例では暗黙のGOTOがあります(try/catchは本質的に' GOTOは、何か悪いことが起こったらキャッチします ')。

例外がスローされた場合、final変数は初期化されません。

静的構造の使用は、オブジェクト指向の教義に反することに注意してください。テストが複雑になり、デバッグが難しくなる場合があります。

35
SyntaxT3rr0r

これを行うことはできますが、例外をスローして静的ブロックを終了する必要があります。キャッチされた例外または新しい例外を再スローできます。通常、この例外はRuntimeExceptionでなければなりません。汎用のExceptionをキャッチするのではなく、tryブロック内からスローされる可能性のあるより具体的な例外をキャッチする必要があります。最後に、静的初期化子が例外をスローすると、JVMはクラスの初期化を1回しか試行しないため、その特定の実行中にクラスが使用できなくなります。このクラスを使用しようとすると、NoClassDefFoundErrorなどの別の例外が発生します。

そのため、イニシャライザは次のように読み取る必要があります。

static {
    try {
        ...
    } catch (Exception e) {
        e.PrintStackTrace();
        throw new InitializationFailedException("Could not init class.", e);
    }
}

InitializationFailedExceptionがカスタムRuntimeExceptionであると仮定しますが、既存のものを使用できます。

18
Kevin Brock
public class MyClass
{
    private static final SomeClass myVar;

    static
    {
        Object obj = null;  // You could use SomeClass, but I like Object so you can reuse it
        try
        {
            obj = new SomeClass(...);    
        }
        catch(WhateverException err)
        {
            // Possibly nested try-catches here if the first exception is recoverable...
            // Print an error, log the error, do something with the error
            throw new ExceptionInInitializerError(err); 
        }
        finally
        {
            myVar = (SomeClass) obj;
        }
    }
}

ExceptionInInitializationErrorまたは一般的なExceptionその場合、プログラムはmyVarを使用しようとしてはなりません。ただし、それらがキャッチされてプログラムが終了しない場合は、myVarがヌルであることを監視および処理するコードを作成する必要があります(またはNullPointerExceptionsが出てくることに満足してください)。

これを処理する良い方法があるかどうかはわかりません。

9
Matt Vang

Finallyブロックに宣言を配置できますか?

try {
    //load file
} catch(IOException e) {
    // horay
} finally {
    Host=config.get......
}
0
Stephen