我可以在同一个 catch 子句中捕获多个 Java 异常吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3495926/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 01:17:40  来源:igfitidea点击:

Can I catch multiple Java exceptions in the same catch clause?

javaexceptiontry-catchmulti-catch

提问by froadie

In Java, I want to do something like this:

在 Java 中,我想做这样的事情:

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

...instead of:

...代替:

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

Is there any way to do this?

有没有办法做到这一点?

采纳答案by OscarRyz

This has been possible since Java 7. The syntax for a multi-catch block is:

自 Java 7 以来,这已经成为可能。multi-catch 块的语法是:

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

Remember, though, that if all the exceptions belong to the same class hierarchy, you can simply catch that base exception type.

但是请记住,如果所有异常都属于同一个类层次结构,则可以简单地捕获该基本异常类型。

Also note that you cannot catch both ExceptionA and ExceptionB in the same block if ExceptionB is inherited, either directly or indirectly, from ExceptionA. The compiler will complain:

另请注意,如果 ExceptionB 是从 ExceptionA 直接或间接继承的,则您无法在同一块中同时捕获 ExceptionA 和 ExceptionB。编译器会抱怨:

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

回答by duffymo

No, one per customer.

不,每个客户一个。

You can catch a superclass, like java.lang.Exception, as long as you take the same action in all cases.

只要在所有情况下都采取相同的操作,就可以捕获超类,例如 java.lang.Exception。

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

But that might not be the best practice. You should only catch an exception when you have a strategy for actually handling it - and logging and rethrowing is not "handling it". If you don't have a corrective action, better to add it to the method signature and let it bubble up to someone that can handle the situation.

但这可能不是最佳实践。只有当您有实际处理异常的策略时才应该捕获异常 - 并且记录和重新抛出不是“处理它”。如果您没有纠正措施,最好将其添加到方法签名中,并让它冒泡给可以处理这种情况的人。

回答by Vineet Reynolds

Catch the exception that happens to be a parent class in the exception hierarchy. This is of course, bad practice. In your case, the common parent exception happens to be the Exception class, and catching any exception that is an instance of Exception, is indeed bad practice - exceptions like NullPointerException are usually programming errors and should usually be resolved by checking for null values.

捕获恰好是异常层次结构中的父类的异常。这当然是不好的做法。在您的情况下,常见的父异常恰好是 Exception 类,并且捕获作为 Exception 实例的任何异常确实是不好的做法 - 像 NullPointerException 这样的异常通常是编程错误,通常应该通过检查空值来解决。

回答by Michael Shopsin

If there is a hierarchy of exceptions you can use the base class to catch all subclasses of exceptions. In the degenerate case you can catch allJava exceptions with:

如果存在异常层次结构,您可以使用基类来捕获异常的所有子类。在退化情况下,您可以通过以下方式捕获所有Java 异常:

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

In a more common case if RepositoryException is the the base class and PathNotFoundException is a derived class then:

在更常见的情况下,如果 RepositoryException 是基类而 PathNotFoundException 是派生类,则:

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

The above code will catch RepositoryException and PathNotFoundException for one kind of exception handling and all other exceptions are lumped together. Since Java 7, as per @OscarRyz's answer above:

上面的代码将捕获 RepositoryException 和 PathNotFoundException 用于一种异常处理,并将所有其他异常集中在一起。从 Java 7 开始,根据上面@OscarRyz 的回答:

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

回答by crusam

Within Java 7 you can define multiple catch clauses like:

在 Java 7 中,您可以定义多个 catch 子句,例如:

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

回答by user454322

Not exactly before Java 7 but, I would do something like this:

不完全在 Java 7 之前,但是,我会做这样的事情:

Java 6 and before

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



爪哇 7

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

回答by Oleg Vaskevich

A cleaner (but less verbose, and perhaps not as preferred) alternative to user454322's answer on Java 6 (i.e., Android) would be to catch all Exceptions and re-throw RuntimeExceptions. This wouldn't work if you're planning on catching other types of exceptions further up the stack (unless you also re-throw them), but will effectively catch all checkedexceptions.

用户454322在Java 6(即Android)上的答案的更清洁(但不那么冗长,也许不是首选)替代方案是捕获所有Exceptions并重新抛出RuntimeExceptions。如果您计划在堆栈中进一步捕获其他类型的异常(除非您也重新抛出它们),这将不起作用,但会有效地捕获所有已检查的异常。

For instance:

例如:

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

That being said, for verbosity, it might be best to set a boolean or some other variable and based on that execute some code after the try-catch block.

话虽如此,对于冗长,最好设置一个布尔值或其他一些变量,并基于它在 try-catch 块之后执行一些代码。

回答by Bill S

In pre-7 how about:

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

回答by Shiva

Yes. Here's the way using pipe( | ) separator,

是的。这是使用管道(|)分隔符的方法,

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

回答by Dr.Hymany

For kotlin, it's not possible for now but they've considered to add it: Source
But for now, just a little trick:

对于 kotlin,目前不可能,但他们已经考虑添加它:Source
但是现在,只是一个小技巧:

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