Могу ли я поймать несколько исключений 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 ответов


это возможно начиная с 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
    } 
}

это, как говорится, для многословия, было бы лучше установить boolean или какая-либо другая переменная и на основе этого выполнить некоторый код после блока 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.
  }

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


да. Вот как использовать разделитель pipe ( / ),

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