1、结构

最顶层的类是序列化类,作用,异常堆栈信息可以通过网络流传送,Throwable是顶层的异常类(你可以看到所有的子类的构造函数都是调用父类的构造器,最后到达Throwable),Exception作为Throwable和其他异常的桥梁(这样更好的扩展异常类,比如自定义异常)。
2、异常的栈信息是怎么打印出来的
我们接触最多的就是异常可以帮助我们打印堆栈信息,下面通过一个列子说明
try {
InputStream inputStream = new FileInputStream("D://aa");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
主要是看printStackTrace()栈的源码
synchronized (s.lock()) {
// Print our stack trace
s.println(this);
StackTraceElement[] trace = getOurStackTrace(); //获取堆栈信息
for (StackTraceElement traceElement : trace)
s.println("\tat " + traceElement);
// Print suppressed exceptions, if any
for (Throwable se : getSuppressed())
se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
// Print cause, if any
Throwable ourCause = getCause();
if (ourCause != null)
ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
}
getOurStackTrace()源码
if (stackTrace == UNASSIGNED_STACK ||
(stackTrace == null && backtrace != null) /* Out of protocol state */) {
int depth = getStackTraceDepth(); //获取栈的深度
stackTrace = new StackTraceElement[depth];
for (int i=0; i < depth; i++)
stackTrace[i] = getStackTraceElement(i); //获取栈的信息
} else if (stackTrace == null) {
return UNASSIGNED_STACK;
}
getStackTraceDepth() 和 getStackTraceElement(i)
native int getStackTraceDepth(); //本地方法
native StackTraceElement getStackTraceElement(int index); //本地方法
上诉方法都是在Throwable,从源码可见,其实栈的信息最后都是通过顶层父类Throwable中的方法打印出来,栈的信息是本地方法获取,最后看下异常信息
java.io.FileNotFoundException: D:\aa (系统找不到指定的文件。)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at main.test.Throw.main(Throw.java:30)
如果你仔细看new FileInputStream(String name)构造器的源码的话你会看到执行流程
public FileInputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null);
}
public FileInputStream(File file) throws FileNotFoundException {
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(name);
}
if (name == null) {
throw new NullPointerException();
}
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
fd = new FileDescriptor();
fd.attach(this);
path = name;
open(name); //open
}
private void open(String name) throws FileNotFoundException {
open0(name);
}
private native void open0(String name) throws FileNotFoundException;
看到没有这个是入栈的操作(知识:每个方法都代码一个栈帧),出栈的顺序和入栈顺序是相反的(所以说栈是先进后出的)。
本文详细介绍了Java中的异常处理机制,包括异常类的结构、异常栈信息的打印过程以及异常的具体实现方式。通过示例展示了FileNotFoundException的抛出和捕获过程,并深入分析了Throwable类中涉及的本地方法。
4817

被折叠的 条评论
为什么被折叠?



