Проверяются ли многократно генерируемые исключения или время выполнения?
У меня есть цепочка исключений, в которой 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()
и получил чистую компиляцию?