在 Java 中捕获通用异常?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3024654/
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-13 15:42:33  来源:igfitidea点击:

Catch a generic exception in Java?

javagenericsexception

提问by Alex Baranosky

We use JUnit 3 at work and there is no ExpectedExceptionannotation. I wanted to add a utility to our code to wrap this:

我们在工作中使用 JUnit 3,没有ExpectedException注释。我想在我们的代码中添加一个实用程序来包装它:

 try {
     someCode();
     fail("some error message");
 } catch (SomeSpecificExceptionType ex) {
 }

So I tried this:

所以我试过这个:

public static class ExpectedExceptionUtility {
  public static <T extends Exception> void checkForExpectedException(String message, ExpectedExceptionBlock<T> block) {
     try {
        block.exceptionThrowingCode();
        fail(message);
    } catch (T ex) {
    }
  }
}

However, Java cannot use generic exception types in a catch block, I think.

但是,我认为 Java 不能在 catch 块中使用通用异常类型。

How can I do something like this, working around the Java limitation?

我怎样才能做这样的事情,解决 Java 限制?

Is there a way to check that the exvariable is of type T?

有没有办法检查ex变量的类型T

采纳答案by Mark Peters

You could pass the Class object in and check that programatically.

您可以传入 Class 对象并以编程方式进行检查。

public static <T extends Exception> void checkForException(String message, 
        Class<T> exceptionType, ExpectedExceptionBlock<T> block) {
    try {
       block.exceptionThrowingCode();
   } catch (Exception ex) {
       if ( exceptionType.isInstance(ex) ) {
           return;
       } else {
          throw ex;  //optional?
       }
   }
   fail(message);
}

//...
checkForException("Expected an NPE", NullPointerException.class, //...

I'm not sure if you'd want the rethrow or not; rethrowing would equally fail/error the test but semantically I wouldn't, since it basically means "we didn't get the exception we expected" and so that represents a programming error, instead of a test environment error.

我不确定你是否想要重新抛出;重新抛出同样会使测试失败/错误,但在语义上我不会,因为它基本上意味着“我们没有得到我们预期的异常”,因此这表示编程错误,而不是测试环境错误。

回答by ShadowRanger

Well, you could just catch Exception and rethrow if it's not an expected Exception. Though good coding practice usually dictates that the success path of code should not be defined by an Exception, so you might want to rethink your design.

好吧,如果它不是预期的异常,您可以捕获异常并重新抛出。尽管良好的编码实践通常规定代码的成功路径不应由异常定义,因此您可能需要重新考虑您的设计。

回答by Kevin Bourrillion

I understand the impulse to try to simplify your exception-test idiom, but seriously: don't. Every possible choice you'll come up with is a cure that's worse than the disease. EspeciallyJUnit 4's @ExpectedException nonsense! It is a too-clever frameworky solution, requiring everyone to learn how it works, as opposed to a plain self-evident bit of regular Java code. Worse, it gives you no way to wrap only the part of your test that you expect to throw the exception, so if an earlier setup step throws that same exception, your test will pass even though your code is broken.

我理解试图简化您的异常测试习语的冲动,但说真的:不要。你能想到的每一个可能的选择都是比疾病更糟糕的治疗方法。 尤其是JUnit 4 的 @ExpectedException 废话!这是一个过于聪明的框架解决方案,要求每个人都学习它的工作原理,而不是简单的不言自明的常规 Java 代码。更糟糕的是,它无法让您仅包装您希望抛出异常的测试部分,因此如果较早的设置步骤抛出相同的异常,即使您的代码已损坏,您的测试也会通过。

I could write a long diatribe about this here (I'm sorry for not having enough time to), as we've had a lengthy discussion of this issue among Java engineers here at Google, and the consensus was that none of these crazy solutions are worthwhile. Get used to try/catch, it's really not that bad.

我可以在这里写一篇关于这个的长篇谩骂(我很抱歉没有足够的时间),因为我们在谷歌的 Java 工程师之间对这个问题进行了长时间的讨论,并且一致认为这些疯狂的解决方案都没有是值得的。习惯了try/catch,真的没那么糟糕。

回答by OscarRyz

You can also use an IDE that supports live template ( like IntellJ IDEA for instance) and assign a shortcut like ee -> [tab]that inserts the try/catch/ignore for your and let you type the correct one.

你也可以使用一个IDE,它支持实时模板(如IntellJ IDEA例如),并指定像快捷方式ee -> [tab]进行的插入你的的try / catch /无视,让你输入正确的一个。

like this

像这样

like this

像这样

回答by odoepner

回答by UB Mobile Banking

Generics are not types. They are not templates. They are compile time type checks, in Java. Exception blocks catch on type. You can catch(Exception e) or even catch(Throwable e) and then cast as needed.

泛型不是类型。它们不是模板。它们是 Java 中的编译时类型检查。异常块捕获类型。您可以 catch(Exception e) 甚至 catch(Throwable e) 然后根据需要进行转换。