Проверяются ли многократно генерируемые исключения или время выполнения?

У меня есть цепочка исключений, в которой method1 создает исключение для method2 который бросает исключение на main, По какой-то причине компилятор заставляет меня иметь дело с ошибкой в method2 и помечает это как ошибку, если я не делаю, указывая, что это проверенное исключение. Но когда то же самое Exception брошен дальше вниз по линии к main, компилятор позволяет мне игнорировать это и не отображает никаких ошибок.

Оригинальное исключение в method1 это ParseException, который проверен. Но метод имеет общий throws Exception предложение в заголовке, и тот же объект брошен в method2, который имеет идентичный throws Exception пункт. Когда и как это исключение теряет статус проверки / перехвата компилятором?

Отредактировано, чтобы уточнить:

public void method1() throws Exception{
   // code that may generate ParseException
}

public void method2() throws Exception{
   method1(); //compiler error (if the throws clause is left out)
}

public static void main(String[] args){
   method2(); //ignored by compiler, even though the exception isn't caught or thrown or handled at all
}

Изменить: Извините всех, вопрос был основан на ошибке... Основной метод на самом деле имел throws Exception пункт, который я пропал. Я удалил это, и код теперь ведет себя как ожидалось. Спасибо за помощь!

4 ответа

Решение

Проверено ли исключение или нет, полностью зависит от того, какое это исключение: если оно RuntimeException или его подкласс, это не проверено; в противном случае это так. (И да, RuntimeException это подкласс Exception - один из недостатков дизайна библиотеки Java, но не самый главный.)

Компилятор проверяет сигнатуры методов. Таким образом, фактическое исключение не имеет значения (для этой цели). Если методы говорят throws Exception тогда вы должны поймать Exception в вашем методе или объявить, что метод throws Exception, Методы должны всегда использовать самый узкий из возможных throws пункт - например, не throws Exception но throws ParseException,

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

Редактирование Код, который вы добавили в свой редактор, не скомпилируется: 1. Он вызывает метод экземпляра без экземпляра, и 2. main нужно объявить, что он бросает Exception,

Этот код решает другие проблемы и (правильно) демонстрирует, что main нуждается в throws Exception пункт:

public class CheckTest
{
    public static final void main(String[] params)
    {
        new CheckTest().method2();
    }

    public void method1() throws Exception{
        throw new java.text.ParseException("foo", 2);
    }

    public void method2() throws Exception{
        this.method1();
    }
}

Результат:

CheckTest.java:27: unreported exception java.lang.Exception; must be caught or declared to be thrown

                new CheckTest().method2();
                                       ^
1 error

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

В вашем случае это будет Exception вплоть до корня стека вызовов. Если метод объявлен, чтобы бросить Exception (что методы должны делать очень редко), вызывающий метод должен либо сказать, что он выдает Exception тоже или поймай и разберись с этим.

Редактировать Как в примере в отредактированном OP, он не скомпилируется. Вы можете объявить main бросать Exception если ты не хочешь иметь с этим дело, хотя.

Возможно ли, что ваш компилятор не жалуется на проблему в main() потому что это затрагивает проблему в method2() и перестает проверять синтаксис в этой точке? Оба должны быть ошибкой. Вы исправили звонок в method2() и получил чистую компиляцию?

Другие вопросы по тегам