Невозможно определить частную статическую переменную final, потому что она выдает исключение - PullRequest
19 голосов
/ 03 декабря 2011

У меня есть класс, как:

public class SomeClassImpl implements SomeClass {
   private static final SomeLib someLib = new SomeLib();
}

Я не могу этого сделать, потому что SomeLib генерирует исключение UnknownHostException.

Я знаю, что мог бы переместить создание экземпляра в конструктор, но есть ли для меня способ сделать это так, как я это сделал выше? Таким образом, я могу оставить var помеченным как final.

Я пытался найти, как генерировать исключения на уровне класса, но ничего не могу найти на нем.

Ответы [ 5 ]

44 голосов
/ 03 декабря 2011

Вы можете использовать статический инициализатор:

public class SomeClassImpl implements SomeClass {
   private static final SomeLib someLib;
   static {
     SomeLib tmp = null;
     try {
       tmp = new SomeLib();
     } catch (UnknownHostException uhe) {
       // Handle exception.
     }
     someLib = tmp;
   }
}

Обратите внимание, что нам нужно использовать временную переменную, чтобы избежать ошибки "переменная someLib, возможно, не была инициализирована" и справиться с тем фактом, что мы можем назначить someLib только один раз, потому что она final.

Однако необходимость добавления сложной логики инициализации и обработки исключений к статическому инициализатору часто является признаком более фундаментальной проблемы проектирования. Вы написали в разделе комментариев, что это класс пула соединений с базой данных. Вместо использования статического финала рассмотрите возможность сделать его переменной экземпляра. Затем вы можете выполнить инициализацию в конструкторе или, что еще лучше, в методе статической фабрики.

4 голосов
/ 03 декабря 2011

Вы можете использовать статический инициализатор:

private static final SomeLib SOME_LIB; // respect naming conventions

static {
    try {
        SOME_LIB = new SomeLib();
    }
    catch (UnknownHostException e) {
        throw new RuntimeException("Class initialization failed due to UnknownHostException", e);
    }
}

Обратите внимание, что ваш класс не сможет инициализироваться, если вы это сделаете. Может быть, вы должны попытаться инициализировать lib лениво, когда это необходимо. Такие исключения инициализации класса трудно диагностировать, потому что они преобразованы в ClassNotFoundException или NoClassDefFoundError (я не помню, какой именно)

2 голосов
/ 14 января 2016

Даже чуть более элегантно, чем решение от Адам Зальцман :

public class SomeClassImpl implements SomeClass {
   private static final SomeLib someLib = initSomeLib();

   private static SomeLib initSomeLib() {
     SomeLib someLib = null;
     try {
       someLib = new SomeLib();
     } catch (UnknownHostException uhe) {
       // Handle exception.
     }
     return someLib;
   }

}
0 голосов
/ 24 июня 2016

Этот пример кода даст вам представление об инициализации нескольких переменных без использования статического метода:

public class SomeClass implements SomeOtherClass{

private String string1= getValues("/var/log/log1.txt");
private String component = getValues("/var/log/log2.txt");

private String getValues(String file) {
        try {
          return  new Scanner(new File(file)).next();
        }catch(FileNotFoundException ioe){
            System.out.println("File not found :: " +ioe);
        }
        return null;
    }
0 голосов
/ 03 декабря 2011

Если инициализация переменной, скорее всего, не удастся, то, скорее всего, плохой кандидат на статичность.

Статика хороша для [эффективных] неизменяемых, (с осторожностью) кэшей неизменяемых и всего остального.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...