В Java - Final переменные можно инициализировать в статическом блоке инициализации?

На основании моего понимания языка программирования Java, статические переменные можно инициализировать в статическом блоке инициализации.

Однако, когда я пытаюсь реализовать это на практике (статический переменные окончательной тоже), я получаю сообщение об ошибке показано на скриншоте ниже:

Решение

Да конечно: переменных статические заключительные можно инициализировать в статическом блоке но.... у вас в этом примере подразумевается Гото (попробовать/поймать в основном 'Гото поймать, если случается что-то плохое').

Если исключение выдается вашим "конечным" переменные будут инициализированы.

Обратите внимание, что использование статических конструкций противоречит объектно-ориентированного догма. Это может осложнить ваше тестирование и отладка сложнее.

Комментарии (8)

Вы можете сделать это, но вы должны выйти из статического блока, выдавая исключение - вы можете повторно сгенерировать исключение, что был пойман или новый. Как правило, это исключение должно быть к RuntimeException. Вы действительно не должны поймать универсального "исключение", но более конкретных исключений(ы), которые могут быть созданы из вашего "попробовать" блока. Наконец, если статический инициализатор вызывает исключение, то это окажет класса в негодность в течение этого конкретного бежать, потому что JVM будет только попытка инициализации класса. Последующие попытки использовать этот класс в результате другого исключения, такие какошибке типа noclassdeffounderror`.

Так, для работы, ваш инициализатор должен читать что-то вроде этого:

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

Предполагая, что InitializationFailedException обычай к RuntimeException, но вы можете использовать уже существующий.

Комментарии (1)
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 или вообще исключение тогда программа никогда не должны пытаться использовать аргумент myVar. Однако, если те попадутся и программа не'т конец, тогда нужно код смотреть и ручки аргумент myVar равенство нулю (или быть счастливым с возникновению исключительных ситуаций типа NullPointerException выходит за все).

Я'м не уверен, что есть хороший способ справиться с этим.

Комментарии (1)

Вы можете поместить объявление в блоке finally?

try {
    //load file
} catch(IOException e) {
    // horay
} finally {
    HOST=config.get......
}
Комментарии (1)