1 jvm如何捕获异常:jvm内部实现,暂时未知
2 jvm如何处理异常:代码能够捕获到的异常,即用try...catch捕获到的异常,看下面的第3点;代码未能捕获到的异常jvm会调用Thread的dispatchUncaughtException方法
3 try..catch...finally处理异常,下面是java代码和javap -c获取的汇编指令
package indi.wangx.java.exception;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class ExceptionTest {
public void testException() throws IOException{
int a = 0;
try {
InputStream in = new FileInputStream(new File(""));
in.close();
} catch(NullPointerException e) {
a = 1;
} finally {
a = 2;
}
InputStream in = new FileInputStream(new File(""));
}
}
(1)jvm捕捉到异常后会去查方法的Exception table,如果在捕捉的范围内就执行相应的指令。
(2)Exception table的结构包含4块内容:from、to、target、type
from:异常捕捉范围的第一条指令
to:捕获到异常后正常跳转的代码指令地址。
target:捕获到异常后的处理指令
type:要捕获的异常的类型
(3)finally
- 其中有个异常类型是any,我认为是finally的作用,应该是jvm根据finally生成的异常信息。有的时候会生成多个any,原因是在catch块中也可能发生异常。
- finally中的代码指令会直接放在catch指令块(如果有的话)后面,并且有几个catch块就会生成多少finally块的代码指令。
4 dispathUncaughtException异常处理,下面是Thread、ThreadGroup的源码
/**
* Dispatch an uncaught exception to the handler. This method is
* intended to be called only by the JVM.
*/
private void dispatchUncaughtException(Throwable e) {
getUncaughtExceptionHandler().uncaughtException(this, e);
}
/**
* Returns the handler invoked when this thread abruptly terminates
* due to an uncaught exception. If this thread has not had an
* uncaught exception handler explicitly set then this thread's
* <tt>ThreadGroup</tt> object is returned, unless this thread
* has terminated, in which case <tt>null</tt> is returned.
* @since 1.5
* @return the uncaught exception handler for this thread
*/
public UncaughtExceptionHandler getUncaughtExceptionHandler() {
return uncaughtExceptionHandler != null ?
uncaughtExceptionHandler : group;
}
@FunctionalInterface
public interface UncaughtExceptionHandler {
/**
* Method invoked when the given thread terminates due to the
* given uncaught exception.
* <p>Any exception thrown by this method will be ignored by the
* Java Virtual Machine.
* @param t the thread
* @param e the exception
*/
void uncaughtException(Thread t, Throwable e);
}
// ThreadGroup的uncaughtException方法
public void uncaughtException(Thread t, Throwable e) {
if (parent != null) {
parent.uncaughtException(t, e);
} else {
Thread.UncaughtExceptionHandler ueh =
Thread.getDefaultUncaughtExceptionHandler();
if (ueh != null) {
ueh.uncaughtException(t, e);
} else if (!(e instanceof ThreadDeath)) {
System.err.print("Exception in thread \""
+ t.getName() + "\" ");
e.printStackTrace(System.err);
}
}
}
通过查看相关源码及注释得知:dispatchUncaughtException方法只能由JVM调用,但是具体的实现是由UnncaughtExceptionHandler或者ThreadGroup的uncaughtException处理,在使用中先自定义一个UnncaughtExceptionHandler,然后设置线程的UnncaughtExceptionHandler就行了。