简体   繁体   English

捕获几个异常并重新抛出一般异常

[英]Catching several exceptions and rethrowing a general exception

I'm using reflection to add some data to a private variable inside a class from a third-party library. 我正在使用反射将一些数据添加到来自第三方库的类中的私有变量。 Along the way there are about four different Exceptions that can be thrown; 一路上有大约四种不同的例外可以抛出; all of them are related to reflection, and all of them are very unlikely to occur. 所有这些都与反思有关,而且所有这些都不太可能发生。 I'm hardcoding the name of the class and variable involved. 我正在硬编码所涉及的类和变量的名称。 I'm unlikely to receive any class not found or field not found errors, unless the library gets upgraded some day and has changed significantly. 我不太可能收到任何未找到的课程或找不到字段的错误,除非图书馆有一天升级并且已经发生了重大变化。

I'd rather not declare all four of these exceptions for my caller to handle. 我宁愿不为我的调用者声明所有这四个异常来处理。 He's likely to never see them. 他可能永远不会见到他们。 I'd like to just catch all of these and throw another exception to say "A Java reflection error has occured; it is likely that the library has been upgraded and changed in a way incompatible with this method." 我想抓住所有这些并抛出另一个例外,说“发生了Java反射错误;可能是库已经以与此方法不兼容的方式升级和更改了。” Is there a standard Java Exception I can throw that indicates just a general reflection error? 是否存在我可以抛出的标准Java异常,它表示只是一般反射错误? Should I define my own? 我应该定义自己的吗? Or would it be best to just declare that this method can throw all of the possible reflection exceptions? 或者最好只声明此方法可以抛出所有可能的反射异常?

I usually ask myself these questions: 我经常问自己这些问题:

  • Can whomever calls this method handle these different exception types differently? 是否可以调用此方法以不同方式处理这些不同的异常类型?
  • ...Or would they treat them all the same? ......或者他们会一直对待他们吗?
  • Can the caller/user even recover from this error? 呼叫者/用户甚至可以从此错误中恢复吗?

If the calling code is likely to treat all four of these exceptions the same (as an unrecoverable error), then it absolutely makes sense to capture each of them and re-throw a more general (single) exception. 如果调用代码可能会将所有这四个异常视为相同(作为不可恢复的错误),那么捕获每个异常并重新抛出更一般的(单个)异常绝对是有意义的。 If you do, make sure you attach the generated exception as an inner exception, just to help any debugging or troubleshooting on the other end. 如果这样做,请确保将生成的异常作为内部异常附加,以帮助进行另一端的任何调试或故障排除。

There is some controversy about checked vs unchecked exceptions. 关于已检查与未经检查的异常存在一些争议。 Personally I think checked exceptions are the worst idea in Java--but that's just an opinion (however I'm not alone thinking that) 就个人而言,我认为已检查的异常是Java中最糟糕的想法 - 但这只是一种观点(但我并不是唯一的想法)

Anyway, I think the important thing would be to change them to either a single unchecked exception. 无论如何,我认为重要的是将它们更改为单个未经检查的异常。 More often than not I use a single one like IllegalStateException or IllegalParameterException--with a clear text description, those two exceptions cover 90% of the crap that can go wrong with a method. 通常情况下,我使用像IllegalStateException或IllegalParameterException这样的单一文件 - 带有明确的文本描述,这两个例外涵盖了方法可能出错的90%的垃圾。

First off, don't use reflection unless you really, really have to, because it is evil. 首先,不要使用反射,除非你真的,真的必须,因为它是邪恶的。 Assuming you do have to: 假设您必须:

As you are hardcoding all the names, it just leaves Method.invoke , Constructor.newInstance and Field.get/set . 当您对所有名称进行硬编码时,它只会离开Method.invokeConstructor.newInstanceField.get/set I'd suggest just rethrowing the checked exceptions you can deal with wrapped in Error . 我建议只需重新抛出可以处理包含在Error的已检查异常。 They shouldn't happen, and if you want to deal with it I suggest doing the check at class intialisation time. 它们不应该发生,如果你想处理它,我建议在课堂初始化时进行检查。 InvocationTargetException should, of course, be unwrapped and dealt with in an appropriate manner (throw a wrapped Error for checked exception which the method/constructor did not declare). 当然, InvocationTargetException应该以适当的方式解包和处理(为方法/构造函数未声明的已检查异常抛出一个包装的Error )。

You can turn all the Exceptions into an AssertionError if you never expect them to occur. 如果您从未期望它们发生,您可以将所有异常转换为AssertionError。 InvocationTargetException can be unwrapped if you want to deal with a specific exception. 如果要处理特定异常,可以解包InvocationTargetException。 If you want to throw the actual exception thrown by the method rather than InvocationTargetException you can use this trick, but it may be more confusing than useful 如果你想抛出方法引发的实际异常而不是InvocationTargetException,你可以使用这个技巧,但它可能比有用更令人困惑

} catch (InvocationTargetException e) {
    // Throw any exception in the current thread (even if it is a checked exception)
    Thread.currentThread().stop(e.getCause());
}

How about having those Exception classes extended from a GeneralException and catch that that GeneralException? 如何从GeneralException扩展这些Exception类并捕获那个GeneralException?

I'll try this right now! 我现在就试试吧! :) :)

I don't think it makes sense to declare exceptions in this case. 我不认为在这种情况下声明异常是有意义的。 So I would catch the exceptions from reflection, maybe log a stack trace, and throw some RuntimeException, which has the advantage that it doesn't need to be declared. 所以我会从反射中捕获异常,可能会记录堆栈跟踪,并抛出一些RuntimeException,它的优点是不需要声明它。 You could just use RuntimeException with a suitable message, if you are lazy. 如果你很懒,你可以使用RuntimeException和合适的消息。

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

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