Обработка исключений Java

#java #exception-handling

#java #исключение

Вопрос:

У меня есть следующий код. В этом fn2 фактически генерируется исключение, и оно перехватывается в самой функции. В функции fn1 компилятор жалуется на необработанное исключение, поскольку fn2 объявлено, что оно генерирует исключение.

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

Пожалуйста, объясните поведение.

 public class ExepTest {

/**
 * @param args
 */
public static void main(String[] args) {

    ExepTest exT = new ExepTest();
    exT.fn1();

}
public void fn1(){
    fn2();//compilation error
}
public void fn2() throws Exception{

    try{
        throw new Exception();
    }
    catch(Exception ex){
        System.out.println("Exception caught");
    }
}
}
  

Ответ №1:

Компилятор не знает / не может знать, что во время выполнения никакое исключение не будет выдано fn2() , поскольку объявлено, что оно может выдавать исключение, вот почему вы получили ошибку.

Комментарии:

1. Другими словами: если вы скажете ему , что a использует методы throws Exception , то компилятор поверит вам . Он не будет проверять, так ли это на самом деле (в некоторых случаях он даже не может проверить).

2. @Joachim: Это отношения, основанные на взаимном доверии.

Ответ №2:

Удалите подпись throws Exception из fn2()

Ответ №3:

Сигнатура метода fn2 — это все, что здесь имеет значение. В этой подписи вы заявляете, что fn2 может выдавать исключение. Любой код, вызывающий метод, который может вызвать исключение, должен обрабатывать исключение eexception.

Ответ №4:

public void fn2() throws Exception . Компилятор видит это объявление и ожидает, что каждый вызывающий объект fn2 будет обрабатывать / повторно генерировать исключение.

Ответ №5:

Исключение генерируется fn2 , а не внутри него. Таким образом, он будет фактически выдан там, где он вызывается. Поскольку он вызывается в fn1 , он ведет себя следующим образом.

Ответ №6:

Вам нужно поместить вызов на fn2() в блок try-catch или объявить, что fn1 также генерирует исключение.

Ответ №7:

 public void fn1(){
    fn2();//compilation error
}
public void fn2() throws Exception{

    try{
        throw new Exception();
    }
    catch(Exception ex){
        System.out.println("Exception caught");
    }
}
}
  

Здесь компилятор не распознает, обработали вы исключение или нет. Это просто предполагает, что fn2 выдает исключение, как вы объявили, и именно поэтому оно показывает ошибку.

Чтобы запустить программу, либо удалите throws Exception из fn2, напишите throws Exception в fn1, либо обработайте ее в try..catch в fn1.