Почему основной метод не перехватит необработанное исключение из блока catch - PullRequest
2 голосов
/ 17 октября 2011

Я придумал этот пример во время изучения пробных экзаменов для сертификации OCPJP,
(из http://www.certpal.com версия 1.6 экзамен, часть 3, Контроль потока, Вопрос № 8)

public class Oak 
{
    public static void main(String args[])  
    {
        try
        {
            Integer i =null;
            i.toString();
        }
        catch (Exception e)
        {
            try
            {
                System.out.println("One ");
                Integer i =null;
                i.toString();                
            }
            catch (Exception x)
            {
                System.out.println("Two ");
                Integer i =null;
                i.toString();                   
            }
            finally
            {
                System.out.println("Three ");
                Integer i =null;
                i.toString();                            
            }
        }
        finally
        {
            System.out.println("Four ");
        }
    }
}

Я полностью осознаю, что, наконец, блоки всегда выполняются, если только нет System.exit (), поэтому я проследил программу и решил, что она будет иметь такой вывод

Исключение One Two в потоке "main" java.lang.NullPointerException Исключение Three в потоке "main" java.lang.NullPointerException Four

Однако получается, что правильный вывод (согласно отладке сайта и Eclipse)

Исключение один два три четыре в теме "main" java.lang.NullPointerException

Что я не понимаю, так это то, куда делось исключение, которое происходит в блоке catch с "Two"?

Под ним нет блока перехвата, разве он не должен быть запущен основным потоком? Потому что это не ловится?

1 Ответ

7 голосов
/ 17 октября 2011

Это исключение фактически теряется - если блок finally генерирует исключение, любое исключение, которое было в процессе распространения, становится неактуальным, и результатом блока finally является новое исключение.

Точно так же, если вы вернете в блоке finally, этот общий try / catch / finally никогда не выдаст исключение.

Подробнее см. раздел 14.20.2 спецификации языка Java . В частности, различные биты, подобные этому:

Если блок finally завершается преждевременно по какой-либо причине, то оператор try завершается преждевременно по той же причине.

...