我正在使用反射将一些数据添加到来自第三方库的类中的私有变量中。一路上有大约四种不同的例外可以抛出;所有这些都与反思有关,而且所有这些都不太可能发生。我正在硬编码所涉及的类和变量的名称。我不太可能收到任何未找到的课程或找不到字段的错误,除非图书馆某天升级并且发生了重大变化。
我宁愿不为我的调用者声明所有这四个异常来处理。他可能永远不会见到他们。我想抓住所有这些并抛出另一个例外,说“发生了Java反射错误;可能是库已经以与此方法不兼容的方式升级和更改了。”是否存在我可以抛出的标准Java异常,它表示只是一般反射错误?我应该定义自己的吗?或者最好只声明这个方法可以抛出所有可能的反射异常?
答案 0 :(得分:6)
我经常问自己这些问题:
如果调用代码可能会将所有这四个异常视为相同(作为不可恢复的错误),那么捕获每个异常并重新抛出更一般的(单个)异常绝对有意义。如果这样做,请确保将生成的异常作为内部异常附加,以帮助进行另一端的任何调试或故障排除。
答案 1 :(得分:2)
关于已检查与未检查的异常存在一些争议。就个人而言,我认为已检查的异常是Java中最糟糕的想法 - 但这只是一种观点(但我并不是唯一认为的那样)
无论如何,我认为重要的是将它们更改为单个未经检查的异常。通常情况下,我使用像IllegalStateException或IllegalParameterException这样的单一文件 - 带有明确的文本描述,这两个例外涵盖了90%的方法可能出错的垃圾。
答案 2 :(得分:2)
首先,不要使用反射,除非你真的,真的必须,因为它是邪恶的。假设您必须:
当您对所有名称进行硬编码时,它会离开Method.invoke
,Constructor.newInstance
和Field.get/set
。我建议你重新抛出你可以处理的Error
包含的已检查异常。它们不应该发生,如果你想处理它,我建议在课堂初始化时进行检查。当然,InvocationTargetException
应该以适当的方式解包和处理(抛出一个包装的Error
用于检查异常,方法/构造函数没有声明)。
答案 3 :(得分:2)
如果您不希望它们发生,您可以将所有异常转换为AssertionError。 如果要处理特定异常,可以解包InvocationTargetException。 如果你想抛出方法而不是InvocationTargetException引发的实际异常,你可以使用这个技巧,但它可能比有用更麻烦
} catch (InvocationTargetException e) {
// Throw any exception in the current thread (even if it is a checked exception)
Thread.currentThread().stop(e.getCause());
}
答案 4 :(得分:1)
如何从GeneralException扩展这些Exception类并捕获那个GeneralException?
我现在就试试吧! :)
答案 5 :(得分:0)
我不认为在这种情况下声明例外是有意义的。 所以我会从反射中捕获异常,可能会记录堆栈跟踪,并抛出一些RuntimeException,它的优点是不需要声明它。 如果你很懒,你可以使用RuntimeException和合适的消息。