Конструкция try-catch-finally в Java. Finally выполняется всегда. Это знают все. А что если в finally стоит return, а в try или catch случился exception?
Вот такой примерчик. Предположим у нас есть наш собственный checked my.ArithmeticException которым мы оборачиваем стандартный unchecked ArithmeticException по каким-то своим причинам. Как-то так:
- int result = 0;
- try{
- result = a / b;
- }
- }
- finally{
- return result;
- }
Запускаем. Для входных параметров 12345 и 0 (деление на 0) наш exception не бросается а результат операции равен нулю.
Что же произошло? Почему отработал return а не throws?
Разберемся, как работает JVM при выходе из метода. Выход из метода - значение на стеке. И throws и return занимают её место, когда работа метода завершается. В нашем случае, в стек сначала попадает throws my.ArithmeticException, затем начинает работать finally который кладет на стек return и перетирает наш exception. Он теряется. Навсегда.
Как это может быть полезно? Да никак. Если уж очень надо чтобы метод всегда завершал работу штатно (например) , обычно пишут catch(Throwable) в котором хотя бы можно залогировать проблему перед тем как ее игнорировать. Finally + return затирает ВСЕ (да-да, и OutOfMemory тоже) exception'ы и вы никак об этом не узнаете.
Наверное единственный правильный вывод к которому я пришел - не писать return в finally.