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


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

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

...вместо:

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

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

9 572

9 ответов:

это возможно начиная с Java 7. Синтаксис блока try-catch:

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

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

Edit: обратите внимание, что в Java 7 Вы не можете поймать оба ExceptionA и ExceptionB в одном блоке, если ExceptionB наследуется, либо прямо или косвенно, с исключ. Компилятор будет жаловаться: The exception ExceptionB is already caught by the alternative ExceptionA.

не совсем до 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();
}

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

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

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

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

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

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

Если есть иерархия исключений вы можете использовать базовый класс, чтобы поймать всех подклассов исключений. В вырожденном случае вы можете поймать все исключения 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 ) { 
  ...
}

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

например:

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
    } 
}

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

в pre-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.
  }

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

да. Вот как использовать разделитель труб ( | ),

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