简体   繁体   English

在Java中抛出多个已检查的异常有什么问题?

[英]What's wrong with throwing multiple checked exceptions in Java?

Consider the Java code snippet below: 考虑下面的Java代码片段:

public <T> T create(Class<T> clazz) throws InstantiationException, IllegalAccessException {
    return clazz.newInstance();
}

This in Eclipse (Neon.2, JDK 8) with SonarLint performing static code analysis. 这在Eclipse(Neon.2,JDK 8)中使用SonarLint执行静态代码分析。 It is providing a recommendation to refactor this: 它提供了重构的建议:

Refactor this method to throw at most one checked exception instead of: java.lang.InstantiationException, java.lang.IllegalAccessException 重构此方法最多抛出一个已检查的异常而不是:java.lang.InstantiationException,java.lang.IllegalAccessException

What best practice is the basis for this recommendation? 最佳做法是此建议的基础? I understand there's some controversy about checked exceptions in general, but why would it be better in this instance to catch one here and pass the other up the stack vs. passing them both up the stack for something else to handle them? 我理解一般来说有一些关于已检查异常的争议 ,但是为什么在这个实例中捕获一个并将另一个传递到堆栈而不是将它们传递到堆栈以获得其他处理它们会更好?

I agree with @David it is opinion based, though in my opinion it is best practice to throw one single exception from a method based on single responsibility principle. 我同意@David这是基于意见的,但在我看来,最好的做法是从基于单一责任原则的方法中抛出一个例外。 When multiple exceptions are thrown it sounds like the method is implemented to perform multiple tasks which is not ideally a good practice though each one of us do it that way quite often. 当抛出多个异常时,听起来该方法被实现为执行多个任务,尽管我们每个人都经常这样做,但这并不是一个理想的做法。 When such a need is there it is better to throw a custom exception by mentioning the problem with an appropriate error code or error message 当有这样的需求时,最好通过提及适当的错误代码或错误消息的问题来抛出自定义异常

What best practice is the basis for this recommendation? 最佳做法是此建议的基础?

"Best practice" implies that there is a single objectively correct answer to the question. “最佳实践”意味着对该问题有一个客观正确的答案。 There isn't one. 没有一个。

Why would it be better in this instance to catch one here and pass the other up the stack vs. passing them both up the stack for something else to handle them? 为什么在这个实例中捕获一个并将另一个传递到堆栈而不是将它们传递到堆栈以便处理它们之类的东西会更好?

In this case, you wouldn't do that. 在这种情况下,你不会这样做。 Both IllegalAccessException and InstantiationException are subtypes of ReflectiveOperationException . IllegalAccessExceptionInstantiationException都是ReflectiveOperationException子类型。 If you wanted to reduce the signature to a single checked exception (as suggested by the checker) you would use that exception. 如果您想将签名减少到单个已检查的异常(如检查器所建议的那样),您将使用该异常。

In general, the argument for unifying (by either picking an existing superclass or by redesigning the exception hierarchy) is that the caller needs to handle fewer exceptions. 通常,统一(通过选择现有的超类或通过重新设计异常层次结构)的参数是调用者需要处理更少的异常。

But the counter-argument to that is that when you unify the throws list, you are hiding information from the programmer / compiler. 但反驳的是,当您统一抛出列表时,您将隐藏程序员/编译器中的信息。 For example if the API was changed to this: 例如,如果API已更改为:

public <T> T create(Class<T> clazz) throws ReflectiveOperationException {
    ...
}

programmer using that API no longer knows which kinds of reflective operation exception can be thrown. 使用该API的程序员不再知道可以抛出哪种反射操作异常。 And when you "unify" by catching, wrapping and throwing as a new exception, it is even worse. 当你通过捕捉,包装和投掷“统一”作为一个新例外时,情况更糟。

Note that I'm not saying that either approach is wrong. 请注意,我并不是说这两种方法都是错误的。 What I'm saying is that the context should determine which approach you take. 我所说的是上下文应该决定你采取哪种方法。 In other words, appealing to "best practice" is missing the point. 换句话说,对“最佳实践”的吸引力忽略了这一点。

public class IllegalAccessException
extends ReflectiveOperationException

An IllegalAccessException is thrown when an application tries to reflectively create an instance (other than an array), set or get a field, or invoke a method, but the currently executing method does not have access to the definition of the specified class, field, method or constructor. 当应用程序尝试反射创建实例(数组除外),设置或获取字段或调用方法时,抛出IllegalAccessException ,但当前正在执行的方法无法访问指定类的字段,字段,方法或构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM