Java 抛出IOException而不是Exception

Java 抛出IOException而不是Exception,java,exception,ioexception,Java,Exception,Ioexception,我有method1(),它在整个代码中由许多其他方法调用。这是方法的签名: public void method1(final Properties properties) throws IOException {} 所有调用此方法的方法也会引发IOException method1()中的实际代码已更改,因此现在它不再抛出IOException,而是抛出一些扩展Exception和而不是IOException的其他异常 我不想更改所有调用method1()的方法的签名 创建IOExcept

我有method1(),它在整个代码中由许多其他方法调用。这是方法的签名:

 public void method1(final Properties properties) throws IOException {}
所有调用此方法的方法也会引发IOException

method1()中的实际代码已更改,因此现在它不再抛出IOException,而是抛出一些扩展Exception和而不是IOException的其他异常

我不想更改所有调用method1()的方法的签名

创建IOException并仍然从method1()引发IOException,从而引发调用method1()的方法,这样可以吗

如下所示:

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

您需要将原始异常保存为原因,这样就不会丢失原始消息或堆栈跟踪。在代码示例中调用
e.getCause()
会跳过捕获的异常并获取其原因,这看起来很可疑

另外,最好指定方法捕获的特定异常,而不是使用catch-all异常类型。捕获异常将导致捕获以前未捕获的NullPointerException之类的内容

这里最好的做法是将方法引发的异常更改为自定义类型,这样就不会让实现细节渗透到调用方。您的方法签名应更改为

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

,您应该这样做,因为阅读您的代码或stacktraces会让其他开发人员感到困惑

从软件设计的角度来看,错误发生得更早。 如果您的代码类似于API并被其他人使用,那么最好使用自定义异常并将IOException包装为根本原因


如果您有完整的源代码,您应该重构源代码并添加另一个异常签名。

这在技术上是可行的

但是,捕获
异常
可丢弃的
几乎每次都是一个坏主意(就像抛出它们一样),因为除了
运行时异常
,您还将捕获所有其他异常

如果您可以更改所有调用类的代码(即,您不是在开发框架/库),那么您应该这样做。因为我假设您的意思是
method1()
现在抛出一个更具体的类型

您还可以考虑抛出一个不需要捕获的
RuntimeException
子类型,对于无法纠正的错误(例如错误配置),这是一个好主意。
(请参阅Robert Martin编写的Clean Code)

这会起作用,但对我来说它看起来相当脏,因为您正在丢失实际引发的异常类型所携带的信息。当我有e.getCause()和e.getMessage()时,他们没有给我实际的异常和与该异常相关的信息吗?我宁愿直接使用
Throwable
构造函数:
newioexception(e)
,这样当捕捉到IOException时,可以使用
myIOException.getCause()
检索根异常。此外,这将打印由stacktrace中的块引起的
,这将有助于调试如果
method1
的所有调用者也抛出
IOException
,他们似乎无法处理它,而且声明异常毫无意义。如果调用方不希望处理
method1
抛出的内容,为什么不抛出一个合适的
RuntimeException
子类型?调用方自己处理或抛出自己的IOException。您是对的,我可以将所有方法(包括method1()的签名改为抛出custom exp.,但我希望避免和此相关的实际代码更改。然而,method1()抛出的exp.将不会也不应该被处理,它将最终出现在错误日志中。我认为这样做是一个非常糟糕的主意。没有人会明白为什么要为数据库异常抛出IOException(如果从文件系统迁移到数据库)。@Christian:是的,我一开始误解了这个问题。对,现在抛出的异常,是:com.google.api.ads.common.lib.exception.oautheexception和com.google.api.ads.common.lib.exception.ValidationException我只能捕获这两个异常,而不是异常。我们也有自定义异常,问题是我不想更改所有调用method1()的方法的签名来抛出任何其他异常,而不是IOException。如果一个IDE中有所有调用类可用,这通常不是什么大问题。。。