Vin*_*yak 38 java exception try-catch throw
考虑:
try {
// Some code here
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw e;
}
Run Code Online (Sandbox Code Playgroud)
throw e
和之间有什么区别throw new Exception(e)
?
try {
// Some code here
} catch (IOException e) {
throw new IOException(e);
} catch (Exception e) {
throw new Exception(e);
}
Run Code Online (Sandbox Code Playgroud)
And*_*lko 47
如果您不需要调整异常类型,则无需更改即可重新抛出(进一步抛出)相同的实例:
catch (IOException e) {
throw e;
}
Run Code Online (Sandbox Code Playgroud)
如果确实需要调整异常类型,则将(原因)包装e
为所需类型的新异常。
catch (IOException e) {
throw new IllegalArgumentException(e);
}
Run Code Online (Sandbox Code Playgroud)
我认为所有其他情况都有代码气味。您的第二个片段就是一个很好的例子。
以下是可能弹出的问题的答案。
我为什么要抛出异常?
你可以放手 但是,如果发生这种情况,您将无法在此级别上执行任何操作。
当我们在方法中捕获异常时,我们仍在该方法中并可以访问其范围(例如,局部变量及其状态)。在抛出异常之前,我们可以做任何需要做的事情(例如,记录一条消息,将其发送到某个地方,对当前状态进行快照)。
我为什么要调整例外?
根据经验,
较高的层应捕获较低级别的异常,并代之以抛出可以根据较高层抽象进行解释的异常。
有效的Java-第2版-项目61:抛出适合于抽象的异常
换句话说,从某种意义上说,一种晦涩IOException
的事物应该转变为一种明显的事物MySpecificBusinessRuleException
。
我称其为“调整异常类型”,聪明的人将其称为异常转换(尤其是异常链接)。
为了清楚起见,让我们举一些愚蠢的例子。
class StupidExample1 {
public static void main(String[] args) throws IOException {
try {
throw new IOException();
} catch (IOException e) {
throw new IOException(new IOException(e));
}
}
}
Run Code Online (Sandbox Code Playgroud)
导致像这样的详细堆栈跟踪
Exception in thread "main" java.io.IOException: java.io.IOException: java.io.IOException
at StupidExample1.main(XXX.java:XX)
Caused by: java.io.IOException: java.io.IOException
... 1 more
Caused by: java.io.IOException
at StupidExample1.main(XXX.java:XX)
Run Code Online (Sandbox Code Playgroud)
可以(并且应该)有效地减少到
Exception in thread "main" java.io.IOException
at StupidExample1.main(XXX.java:XX)
Run Code Online (Sandbox Code Playgroud)
另一个:
class StupidExample2 {
public static void main(String[] args) {
takeString(new String(new String("myString")));
}
static void takeString(String s) { }
}
Run Code Online (Sandbox Code Playgroud)
显然,这new String(new String("myString"))
是一个罗word的版本,"myString"
应重构为后者。
Ant*_*sss 14
catch (IOException e) {
throw e;
}
Run Code Online (Sandbox Code Playgroud)
您将看到仅具有原始stacktrace的原始异常。您不会在堆栈跟踪中看到此“重新抛出”行,因此它是透明的。
catch (IOException e) {
throw new IllegalStateException(e);
}
Run Code Online (Sandbox Code Playgroud)
您将看到created IllegalStateException
和它的堆栈跟踪以及原始异常信息和堆栈跟踪的“原因”。您正在(即将)将抛出的异常设置为新创建的的原因IOException
。上层将看到IllegalStateException
并且可以捕获(您不会捕获该捕获原因异常)。
catch (IOException e) {
throw new IOException();
}
Run Code Online (Sandbox Code Playgroud)
您将仅看到IOException
创建的当前堆栈跟踪,没有添加原因。
归档时间: |
|
查看次数: |
5431 次 |
最近记录: |