Обработка исключений во вложенных методах с глубиной более 2 уровней

#java #exception

Вопрос:

Допустим, у нас есть вложенные методы A, B и C, как показано ниже:

 public void A(){
    try{
        B();
    }
    catch(Exception e){
        log.error(e);
    }
}

public void B(){
    C();
}

public void C(){
    try{
        some_stuff();
    }
    catch(Exception e){
        log.error(e)
    }
}
 

Поскольку я улавливаю исключение в C() и обрабатываю его только с помощью регистрации, а в B () нет никакого подвоха, улавливаю ли я исключение в A()?

Или я должен бросить исключение в C() и добавить пробный захват в B (), чтобы иметь возможность обрабатывать его в A()?

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

1. Зависит от того A , B что и C есть, и что означает/означает исключение. Другими словами, нет единого для всех ответа.

2. Следует создать исключение в C() и B (), тогда вы сможете обработать его в A()

3. Обычно это называется «переосмыслением»-в качестве исключения вы можете найти множество тем, если будете искать их.

4. В общем, вам catch(Exception e) вообще не следует этого делать. Вы должны улавливать точно и только те исключения, которые компилятор заставляет вас улавливать, плюс, возможно, некоторые очень тщательно отобранные RuntimeException s или Error s на сайтах, где вы действительно знаете, что, черт возьми, происходит.

5. @tevemadar Я, конечно, сначала попытался поискать, но не смог найти пример, подобный моему, где у первого и третьего есть улов, а у среднего-нет. Спасибо за термин, тхо, не подумал об этом.

Ответ №1:

Когда вы это сделаете

 public void C(){
    try{
        some_stuff();
    }
    catch(Exception e){
        log.error(e)
    }
}
 

Это обработает исключение на данном этапе. Вы зарегистрируете его и проигнорируете исключение. Если вы хотите войти в систему и распространить его, вам нужно повторно выбросить его из catch предложения.

Поскольку исключение проверено (насколько я помню), вам нужно изменить сигнатуру метода, чтобы указать, что вы выбрасываете это C .

Если B вам не нужно обрабатывать это, вы можете просто изменить сигнатуру метода, чтобы указать, что метод вызывает исключение.

Подробнее о проверенных и непроверенных исключениях Java, например, здесь введите описание ссылки здесь

Наконец, если вы хотите, чтобы A код распространялся, он будет выглядеть так:

 public void A(){
    try{
        B();
    }
    catch(Exception e){
        log.error(e);
    }
}

public void B() throws Exception{
    C();
}

public void C() throws Exception{
    try{
        some_stuff();
    }
    catch(Exception e){
        log.error(e)
        throw e;
    }
}
 

Ответ №2:

Вы обрабатываете исключение в catch блоке, поэтому оно не будет передано вызывающему абоненту. Это не зависит от того, регистрируете ли вы его или делаете с ним что-то еще. Если вы хотите передать его вызывающему абоненту, вам нужно будет повторно бросить его:

 [...]
catch (Exception e) {
   // do something
   throw e;
}
 

То, как вы обрабатываете исключения, зависит от дизайна вашего кода.