简体   繁体   English

引发IOException而不是Exception

[英]Throw IOException instead of Exception

I have method1() which is called from lots of other methods throughout the code. 我有method1(),它在整个代码中都从许多其他方法中调用。 This is the signature of the method: 这是方法的签名:

 public void method1(final Properties properties) throws IOException {}

All methods calling this method also throw IOException. 所有调用此方法的方法也会引发IOException。

The actual code in method1() changed, so now instead of IOException it throws some other exceptions that extend Exception and not IOException anymore. method1()中的实际代码已更改,因此现在它代替IOException引发了其他一些扩展Exception而不是 IOException的异常。

I don't want to change the signature of all methods calling method1(). 我不想更改所有调用method1()的方法的签名。

Is it ok to create IOException and still throw IOException from method1() and hence the methods calling method1()? 是否可以创建IOException并仍然从method1()引发IOException并因此调用method1()的方法?

Something like below: 如下所示:

 Try {
  // code
 } catch (Exception e) {
   throw new IOException(e.getCause());
 }

No , you should not do this, because you will confuse every other developer reading your code or reading stacktraces. ,您不应该这样做,因为您会混淆其他所有阅读代码或阅读堆栈跟踪信息的开发人员。

From the software-design point of view, the error happened a lot earlier. 从软件设计的角度来看,该错误发生的时间要早​​得多。 If your code is like an API and used by others, you may better have used Custom-Exceptions and wrapped the IOException as root-cause. 如果您的代码就像API并被其他人使用,则最好使用Custom-Exceptions并将IOException包装为根本原因。

If you have the complete source, you should refactor the source and add another exception signature. 如果您具有完整的源,则应重构源并添加另一个异常签名。

You need to save the original exception as the cause, so you're not losing the original message or stacktrace. 您需要将原始异常保存为原因,因此您不会丢失原始消息或堆栈跟踪。 Calling e.getCause() in your code example is skipping over the exception that you caught and getting its cause, which is suspicious-looking. 在代码示例中调用e.getCause()会跳过您捕获的异常并获取起因,这看起来很可疑。

Also it would be better to specify the particular exceptions that the method catches, rather than using a catch-all Exception type. 另外,最好指定该方法捕获的特定异常,而不是使用全部捕获的Exception类型。 Catching Exception would result in things like NullPointerExceptions getting caught that were not trapped before. 捕获异常会导致像以前捕获的NullPointerExceptions一样被捕获。

The best thing to do here is change the exceptions thrown by your method to a custom type that doesn't let the implementation details bleed through to the callers. 最好的做法是将方法抛出的异常更改为自定义类型,该类型不允许实现详细信息渗入调用方。 Your method signature should change to 您的方法签名应更改为

public void method1(final Properties properties) throws SomeCustomException {
    try {
        .... // do whatever
    } catch (AException | BException | CException e) {
        throw new SomeCustomException(e);
    }
}

This will work technically. 这将在技术上起作用。

However, catching Exception or Throwable is almost everytime a bad idea (as is throwing them), because you will also catch all other Exceptions, besides RuntimeExceptions . 但是,捕获ExceptionThrowable几乎总是一个坏主意(就像抛出它们一样),因为除了RuntimeExceptions之外,您还将捕获所有其他Exception。

If you can change the code of all calling classes (ie you are not developing a framework/library), you should do so. 如果您可以更改所有调用类的代码(即,您不开发框架/库),则应该这样做。 Because I assume you meant method1() throws a more specific type now. 因为我假设您的意思是method1()现在引发一个更特定的类型。

You may also think about throwing a Subtype of RuntimeException which does not need to be catched, and is a good idea for errors that can't be corrected (eg a bad configuration). 您可能还会考虑抛出一个RuntimeException的子类型,该子类型不需要捕获,对于无法纠正的错误(例如,错误的配置)是个好主意。 (see Clean Code by Robert Martin) (请参阅罗伯特·马丁的清洁代码

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

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