Как оставить перехват ошибок подклассу?

#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