Немедленно перебросить в блоке catch и использовать finally

У меня есть оболочка, отвечающая за ведение журналов, с именем OperationWrapper. Его структура проста и выглядит следующим образом:

public void runOperation(Operation o) throws Exception{ 
     logOperationStarted();
     o.execute();
     logOperationFinished();
}

Поскольку операция "o" может вызвать исключение, метод logOperationFinished() будет вызываться не всегда, и, таким образом, ведение журнала будет работать некорректно.

Кроме того, эти исключения обрабатываются различными компонентами, вызывающими метод runOperation().

Желая гарантировать, что logOperationFinished() будет работать всегда, я реализовал следующую структуру:

public void runOperation(Operation o) throws Exception{ 
     logOperationStarted();
     try{
       o.execute();
     }
     catch(Exception e){
       throw e; 
     }
     finally{
       logOperationFinished();
     }
}

Теперь logOperationFinished() работает всегда, но я получаю предупреждение от IntelliJ:

Перехваченное исключение создается немедленно повторно
Сообщает о любом блоке catch, в котором перехваченное исключение немедленно повторно создается без выполнения над ним каких-либо действий. Такие блоки catch не нужны или в них отсутствует обработка ошибок.

Мне кажется, что IntelliJ не учитывает блок finally при выдаче этого предупреждения.

Я делаю что-то не так или есть лучший способ добиться этого?

Спасибо.


person Shahar    schedule 07.04.2015    source источник
comment
Почему вы ловите его с самого начала, если вы только собираетесь снова бросить его? Это не похоже на то, что вы делаете что-либо с исключением напрямую. (Кроме того, плохая практика ловить Exception — избегайте этого, где можете.)   -  person Makoto    schedule 07.04.2015


Ответы (3)


Используйте блокировку try-finally из JLS 14.20.2. Выполнение try-finally

Если выполнение блока try завершается внезапно по какой-либо другой причине R, то выполняется блок finally, и тогда есть выбор:

  1. Если блок finally завершается нормально, то оператор try завершается внезапно по причине R.

  2. Если блок finally завершается внезапно по причине S, то оператор try завершается внезапно по причине S (и причина R отбрасывается).

public void runOperation(Operation o) throws Exception{ 
     logOperationStarted();
     try{
        o.execute();
     }finally{
       logOperationFinished();
     }
}

Если вы хотите использовать try-catch-finally, это все еще не проблема, вы можете игнорировать предупреждение от IntelliJ или создать новое исключение из блока catch.

throw new ExceptionYouWantToThrow(e);
person Sumit Singh    schedule 07.04.2015

да подвох не нужен

public void runOperation(Operation o) throws Exception{ 
     logOperationStarted();
     try{
       o.execute();
     }
     finally{
       logOperationFinished();
     }
}
person Scary Wombat    schedule 07.04.2015
comment
Хотя это относится к основам Java, иногда кратчайшее решение является лучшим. Вам не нужен улов, он настолько ясен и лаконичен, насколько это возможно. Принятое Сумитом Сингхом решение может быть верным, но ваше решение быстрое и точное, без логики ЕСЛИ А, ТО Б. Спасибо! - person tresf; 28.08.2015

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

Ответ Scary Wombat, скорее всего, вам нужен.

throw new Error(e);

Исключение или ошибка

person user2469515    schedule 07.04.2015