Могу ли я поймать несколько исключений Java в одном и том же предложении catch?

В Java я хочу сделать что-то вроде этого:

try {
    ...     
} catch (/* code to catch IllegalArgumentException, SecurityException, 
            IllegalAccessException, and NoSuchFieldException at the same time */) {
   someCode();
}

... вместо:

try {
    ...     
} catch (IllegalArgumentException e) {
    someCode();
} catch (SecurityException e) {
    someCode();
} catch (IllegalAccessException e) {
    someCode();
} catch (NoSuchFieldException e) {
    someCode();
}

Есть ли способ сделать это?

Ответ 1

Это стало возможным начиная с Java 7. Синтаксис для блока multi-catch:

try { 
  ...
} catch (IOException | SQLException ex) { 
  ...
}

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

Также обратите внимание, что вы не можете перехватить и ExceptionA, и ExceptionB в одном и том же блоке, если ExceptionB наследуется, прямо или косвенно, от ExceptionA. Компилятор будет жаловаться:

Alternatives in a multi-catch statement cannot be related by subclassing
  Alternative ExceptionB is a subclass of alternative ExceptionA

Ответ 2

Не точно до Java 7, но я бы сделал что-то вроде этого:

Java 6 и до

try {
  //.....
} catch (Exception exc) {
  if (exc instanceof IllegalArgumentException || exc instanceof SecurityException || 
     exc instanceof IllegalAccessException || exc instanceof NoSuchFieldException ) {

     someCode();

  } else if (exc instanceof RuntimeException) {
     throw (RuntimeException) exc;     

  } else {
    throw new RuntimeException(exc);
  }

}



Java 7

try {
  //.....
} catch ( IllegalArgumentException | SecurityException |
         IllegalAccessException |NoSuchFieldException exc) {
  someCode();
}

Ответ 3

В Java 7 вы можете определить несколько команд catch, например:

catch (IllegalArgumentException | SecurityException e)
{
    ...
}

Ответ 4

Нет, по одному на каждого клиента.

Вы можете поймать суперкласс, например java.lang.Exception, если вы выполняете одно и то же действие во всех случаях.

try {
    // some code
} catch(Exception e) { //All exceptions are caught here as all are inheriting java.lang.Exception
    e.printStackTrace();
}

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

Ответ 5

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

try {
   ...
} catch (Exception e) {
   someCode();
}

В более распространенном случае, если RepositoryException является базовым классом, а PathNotFoundException является производным классом, тогда:

try {
   ...
} catch (RepositoryException re) {
   someCode();
} catch (Exception e) {
   someCode();
}

Приведенный выше код будет захватывать RepositoryException и PathNotFoundException для одного вида обработки исключений, а все остальные исключения объединяются. Поскольку Java 7, согласно @OscarRyz, ответьте выше:

try { 
  ...
} catch( IOException | SQLException ex ) { 
  ...
}

Ответ 6

Чистое (но менее подробное и, возможно, не столь предпочтительное) альтернативное пользователю answer454322 ответ на Java 6 (т.е. Android) было бы поймать все Exception и повторно бросить RuntimeException s. Это не сработает, если вы планируете улавливать другие типы исключений дальше по стеку (если только вы их не повторно бросаете), но эффективно поймают все проверенные исключения.

Например:

try {
    // CODE THAT THROWS EXCEPTION
} catch (Exception e) {
    if (e instanceof RuntimeException) {
        // this exception was not expected, so re-throw it
        throw e;
    } else {
        // YOUR CODE FOR ALL CHECKED EXCEPTIONS
    } 
}

Если говорить, что для многословия лучше всего установить булевскую или какую-либо другую переменную и на основе этого выполнить некоторый код после блока try-catch.

Ответ 7

В пред-7:

  Boolean   caught = true;
  Exception e;
  try {
     ...
     caught = false;
  } catch (TransformerException te) {
     e = te;
  } catch (SocketException se) {
     e = se;
  } catch (IOException ie) {
     e = ie;
  }
  if (caught) {
     someCode(); // You can reference Exception e here.
  }

Ответ 8

да, вы можете иметь это в Java 7, см. ниже пример

try
{
     //your code
}
catch(SQLException | IOException ex)
{
}

Но вам нужно иметь в виду некоторые правила множественного улова, которые вы можете найти по ссылке ниже http://pictorialjava.blogspot.in/2015/11/exception-handling-in-java-7.html

Ответ 9

Java SE 7 и более поздние операторы множественного улова возможны, как показано ниже.

try{

    //  business logic....

} catch(IOException | SQLException ex){

    // handle exception of both types...

}

Точки ума...

  • Единый блок catch может обрабатывать более одного типа исключения.
  • Оба исключения не должны быть одного типа, т.е. вы не можете поймать исключение подкласса IOException или SQLException в одном блоке catch.

  • Catch параметр ex явно окончательный, вы не можете присвоить ему какое-либо значение.

  • Все исключения должны быть разделены вертикальной трубкой (|).

Ответ 10

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

Ответ 11

try {
   ...     
} catch (IllegalArgumentException | SecurityException | IllegalAccessException | NoSuchFieldException e) {
    //even you can check here like 
    if(e instanceof IllegalArgumentException){
       //like wise you can check the type of the exception, its just an info may not required
    }
    someCode();
}

Ответ 12

Да.. Вы можете...

catch (ArithmeticException | ArrayIndexOutOfBounds | RunTimeException | Exception ex) {       ex.printStackTrace();   }

Вы должны ввести дополнительные особые исключения.. i.e сначала подклассы, а затем суперклассы...

Ответ 13

Да. Здесь путь, использующий разделитель трубы (|),

try
{
    .......
}    
catch
{
    catch(IllegalArgumentException | SecurityException | IllegalAccessException | NoSuchFieldException e)
}

Ответ 14

Для kotlin это пока невозможно, но они решили добавить его: Source
Но пока, маленький трюк:

try {
    // code
} catch(ex:Exception) {
    when(ex) {
        is SomeException,
        is AnotherException -> {
            // handle
        }
        else -> throw ex
    }
}