Как обрабатывать несколько исключений в методе Java?

Я читал, что это не лучшая практика для обработки нескольких исключений, как это:

public void myMethod() throws ExceptionA, ExceptionB, ExceptionC {
    //more code here
}

А затем вызвать myMethod():

try {
    myObject.myMethod();
} catch(Exception e) {
    //More code here
}

Несмотря на то, что исключение является родительским классом для всех других исключений, это считается плохой практикой. Но в моем приложении я использую Java 6 и мне нужно:

  • Делать файловые операции, которые могут подразумевать исключение FileNotFOundException и IOException
  • Объекты Marshal (для создания файлов XML) JAXBException
  • Создайте файл pdf (используя библиотеку pdfbox) COSVisitorException
  • Отправить письмо с помощью JavaMail, MessagingException

Самый простой способ - добавить оператор throws в объявление метода, но что может быть правильным для написания метода клиента?

Можно ли добавить 6 или 7 блоков catch для обработки всех возможных исключений?

1 ответ

Вообще говоря (для Java 6 и ниже), вы должны обрабатывать каждое исключение индивидуально...

try {
    myObject.myMethod();
} catch (ExceptionA e) {
    // Condition for A
} catch (ExceptionB e) {
    // Condition for B
} catch (ExceptionC e) {
    // Condition for C
}

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

В Java 7+ вы можете использовать "multi-catch" или "комбинированный catch" (мы не можем найти "официальный" термин)

try {
    myObject.myMethod();
} catch (ExceptionA | ExceptionB | ExceptionC e) {
    // Condition for A and B and C
}

Но даже тогда вы должны сосредоточить исключения в "общих" группах использования.

try {
    myObject.myMethod();
} catch (ExceptionA | ExceptionB e) {
    // Condition for A and B
} catch (ExceptionC e) {
    // Condition for C
}

Другой вариант, если вы контролируете, как определяются исключения, заключается в расширении из общего базового исключения, хорошим примером этого является FileNotFoundException который простирается от IOException, который брошен FileReader а также FileInputStream (в качестве примера), это означает, что вы можете обрабатывать FileNotFoundException как обычный IOException если вы хотите...

FileReader fr = null;
try {
    fr = new FileReader(new File(...));
    // Read from reader...
} catch (IOException exp) {
    // Common catch block
} finally {
    // Best attempt to close
    try {
        fr.close();
    } catch (Exception exp) {
    }
}

Или вы могли бы справиться с FileNotFoundException как это собственное состояние...

FileReader fr = null;
try {
    fr = new FileReader(new File(...));
    // Read from reader...
} catch (FileNotFoundException exp) {
    // File not found condition
} catch (IOException exp) {
    // Other IO condition
} finally {
    // Best attempt to close
    try {
        if (fr != null) {
            fr.close();
        }
    } catch (Exception exp) {
    }
}

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

Осторожно, хотя, приведенный выше пример, если я поставлю IOException во-первых, FileNotFoundException никогда не будет обрабатываться, при этом убедитесь, что вы используете сначала самые низкие / самые трудные / лучшие исключения, так как они обрабатываются последовательно в указанном вами порядке

Другой вариант (который я не очень заинтересован, но видел) может заключаться в том, чтобы поймать "общего" предка и затем сравнить фактический тип, что позволит вам предоставить общие обработчики для некоторого подтипа исключения.

} catch (IOException exp) {
    if (exp instanceof FileNotFound || exp instanceof FileSystemException) {   
        // Common handling
    } else {
        // Generic handling
    }
}

Это может быть полезно в ситуациях, когда метод выбрасывает только тип предка (т.е. IOException), но вам нужно предоставить более детальное разрешение

Но, опять же, я бы сфокусировался только на обработке ожидаемых "общих" исключений, объявленных как брошенные, не зацикливайтесь на ловле Throwable например

Другие вопросы по тегам