我不熟悉错误/异常处理。
发生了什么"引擎盖下#34;当例外是caught
和thrown
时?
即。在try-catch块中捕获异常然后抛出它有什么意义呢?
E.g:
try {
//Stuff
} catch(StuffException e) {
throw new MyException();
}
}
答案 0 :(得分:5)
关于异常机制的内部工作原理:有很多关于此的文档。 我特别喜欢这篇文章: http://www.javaworld.com/article/2076868/learn-java/how-the-java-virtual-machine-handles-exceptions.html
超短摘要:当抛出异常时,jvm在一个表中查找,其中继续执行(异常的init()方法)。
对于问题的第二部分:
在try-catch块中捕获异常然后抛出它有什么意义?
我看到了抓住另一个例外的一些原因:
您可能想要捕获未经检查的异常(因为您知道, “可能会发生一些不好的事情”)并抛出一个检查过的 - 所以调用者必须处理它。
您想要使用自定义异常,可能需要额外的 信息/逻辑
您正在实施错误外观,例如抛出异常和 在门面的最后抓住它们。
答案 1 :(得分:2)
您的示例捕获具有StuffException类型的内容,然后抛出MyException。这样做是为了抽象出原始的异常;可能是原始异常是一个实现细节,调用它的东西不需要知道(以及哪些需要能够改变,以便调用者不应该依赖它),并抛出异常替换它是已发布的API的一部分,调用者可以依赖它。这是Hibernate的情况,它捕获在调用JDBC函数过程中生成的SQLExceptions,并将它们包装在Hibernate异常中,因此调用代码将它们识别为从Hibernate抛出,并且调用代码不直接依赖于JDBC异常,但是在Hibernate上。如果JDBC改变了它抛出的异常,那么一旦Hibernate适应它,Hibernate的用户就不必改变了。
这个例子的坏处是当e超出范围时,原始StuffException的stacktrace信息被丢弃,而MyException的stacktrace以抛出MyException的位置开始,这使得很难找到实际问题的根源。将旧异常分配给新异常作为其原因将保留原始堆栈跟踪信息:
try {
//Stuff
} catch(StuffException e) {
MyException myException = new MyException();
myException.initCause(e);
throw myException;
}
}
答案 2 :(得分:0)
异常用于处理程序流中通常不会发生的事情。再次抛出异常的重点是更改异常类型,如示例所示。这样做,您可以创建一个自定义异常并将其抛入另一个异常catch块。
修改强>
以下是一个例子:
假设您有一个适用于Thread的方法。你的方法内部有延迟:
Thread.sleep(3000);
但如果你这样写,你会得到一个错误,因为sleep方法声明如下:
void java.lang.Thread.sleep(long millis) throws InterruptedException
所以你必须抓住异常:
try{
Thread.sleep(3000);
}catch(InterruptedException e){
//do stuff
}
现在,您不喜欢InterruptedException,并且希望使用自己的自定义异常来处理它。但是你怎么做,因为睡眠方法只抛出那个特定的异常?答案是:
try{
Thread.sleep(3000);
}catch(InterruptedException e){
throw new CustomException();
}
此时,如果引发了InterruptedException,它将被捕获并且将引发一个CustomException。
答案 3 :(得分:0)
捕获然后抛出异常的一些可能用法:
处理更复杂的异常层次结构
e.g。如果您想要捕获除IOException
(FileNotFoundException
的子类型)之外的所有IOException
,您可以这样做:
try {
...
}
catch (FileNotFoundException e) {
throw e;
}
catch (IOException e) {
// handle exception
}