1

考虑下面的 Java 代码片段:

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

这在 Eclipse(Neon.2,JDK 8)中使用 SonarLint 执行静态代码分析。它提供了重构的建议:

重构此方法以最多抛出一个已检查异常,而不是:java.lang.InstantiationException、java.lang.IllegalAccessException

此建议的基础是什么最佳实践?我知道通常对检查的异常存在一些争议,但是为什么在这种情况下在这里捕获一个并将另一个传递到堆栈而不是将它们都传递到堆栈以供其他东西处理它们会更好?

4

3 回答 3

2

我同意@David,它是基于意见的,尽管在我看来,最好的做法是从基于单一责任原则的方法中抛出一个异常。当抛出多个异常时,听起来该方法是为了执行多个任务而实现的,尽管我们每个人都经常这样做,但这并不是一个理想的好习惯。当有这种需要时,最好通过使用适当的错误代码或错误消息提及问题来引发自定义异常

于 2017-03-25T05:28:43.823 回答
2

此建议的基础是什么最佳实践?

“最佳实践”意味着该问题只有一个客观正确的答案。没有一个。

为什么在这种情况下在这里捕获一个并将另一个传递到堆栈而不是将它们都传递到堆栈以供其他东西处理它们会更好?

在这种情况下,你不会那样做。IllegalAccessException和都是InstantiationException的子类型ReflectiveOperationException。如果您想将签名减少为单个已检查异常(如检查器所建议的那样),您将使用该异常。

通常,统一(通过选择现有的超类或通过重新设计异常层次结构)的论点是调用者需要处理更少的异常。

但与之相反的论点是,当您统一抛出列表时,您正在向程序员/编译器隐藏信息。例如,如果 API 更改为:

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

使用该 API 的程序员不再知道可以抛出哪种反射操作异常。而当你通过捕获、包装和抛出一个新异常来“统一”时,情况就更糟了。

请注意,我并不是说这两种方法都是错误的。我的意思是上下文应该决定你采取哪种方法。换句话说,诉诸“最佳实践”没有抓住重点。

于 2017-03-25T05:48:36.857 回答
-1
public class IllegalAccessException
extends ReflectiveOperationException

当应用程序尝试反射性地创建实例(不是数组)、设置或获取字段或调用方法时,抛出An IllegalAccessException,但当前执行的方法无权访问指定的类、字段、方法的定义或构造函数。

于 2017-03-25T05:16:15.437 回答