#java #java-ee-8
#java #java-ee-8
Вопрос:
public class First {
protected void method1() throws CustomException {
int number=10/0;
System.out.println("method 1" number);
throw new CustomException("Divided by zero");
}
public class Second extends First {
protected void method2() {
method1();
}
public class Third extends Second {
protected void method3(){
try {
method2();
}
catch (CustomException ex)
{
System.out.println("Caught the exception");
System.out.println(ex.getMessage());
}
}
В этом коде сначала генерируется исключение, и я хочу перехватить его из третьего (второй не будет обрабатывать ошибку). Но вызов метода second не позволяет мне пройти. Как я могу это исправить?
Комментарии:
1. не вызывая метод из второго класса. Сделайте этот класс абстрактным и заставьте пользователя использовать дочерний класс
2. Может быть, подробнее объясните, почему это вариант использования / реализация. Для этого ответа есть несколько решений, таких как отсечение посредника, не объявление
CustomException
вmethod1
и т.д.3. Я должен перехват в третьем и записать его детали в файл. Но я не могу удалить вторую. Потому что это своего рода домашнее задание.
4. @Stultuske Извините, но я не понимаю, что вы имеете в виду
5. если пользователю разрешено напрямую вызывать метод в родительском классе, невозможно сказать, что дочерний класс должен обрабатывать исключение. итак, убедитесь, что общедоступны только методы дочерних классов
Ответ №1:
Для проверенных исключений (не каких RuntimeException
-либо) они должны быть либо обработаны, либо выданы методом, который вызывает другой метод, выдающий исключение. Это также более подробно объясняется в руководстве Oracle по исключениям.
Этот пример основан на вашем коде:
class Testing{
public static void main(String[] args) {
Third t = new Third();
t.method3();
}
}
и он выведет:
Caught the exception
Divided by zero
Добавлена отсутствующая реализация CustomException
:
class CustomException extends Exception{
CustomException(){
super();
}
CustomException(String message){
super(message);
}
}
Обратите внимание, что ваш код никогда не будет фактически генерировать ваше исключение, поскольку сначала будет выдано деление на ноль. ArithmeticException
является RuntimeException
и, следовательно, не проверяемым исключением, и оно не требует и не гарантирует какого-либо объявления. Я удалил его, поэтому ваше исключение генерируется:
class First {
protected void method1() throws CustomException {
// will cause "java.lang.ArithmeticException: / by zero" not CustomException
// int number=10/0;
// System.out.println("method 1" number);
throw new CustomException("Divided by zero");
}
} // missing end brace
Причина, по которой вызов вашего Second
метода «не дает мне пройти», заключается в том, что вы создаете Exception
in method1
, который вы вызываете в вызове вашего Second
метода. Итак, вам нужно либо обернуть ваш вызов в method1()
блок try-catch, либо throws
его. Поскольку вы «хотите перехватить ее с третьего», вам нужно throws
указать это в объявлении метода:
class Second extends First {
// error: unreported exception CustomException; must be caught or declared to be thrown
// protected void method2() { // your version
protected void method2() throws CustomException {
method1();
}
} // missing end brace
Это без изменений, за исключением добавленной фигурной скобки:
class Third extends Second {
protected void method3(){
try {
method2();
} catch (CustomException ex) {
System.out.println("Caught the exception");
System.out.println(ex.getMessage());
}
}
} // missing end brace