Throwable
1.Throwable类
Throwable类实现了Serializable 接口,此类可用于序列化
public class Throwable implements Serializable {
private transient Object backtrace;
private String detailMessage;//用于存放异常的详细信息
private Throwable cause = this;//初始化异常原因为本身
private StackTraceElement[] stackTrace;//栈中的轨迹
//四个构造函数
public Throwable() {
fillInStackTrace();
}
public Throwable(String message) {
fillInStackTrace();
detailMessage = message;
}
public Throwable(String message, Throwable cause) {
fillInStackTrace();
detailMessage = message;
this.cause = cause;
}
public Throwable(Throwable cause) {
fillInStackTrace();
detailMessage = (cause==null ? null : cause.toString());
this.cause = cause;
}
public String getMessage() {
return detailMessage;
}
public String getLocalizedMessage() {
return getMessage();
}
public Throwable getCause() {
return (cause==this ? null : cause);//若cause为本身,即初始化时没有赋值,返回null,若已赋值,则返回值
}
2.initCause
初始化cause,一个Throwable类只能设置一次cause
public synchronized Throwable initCause(Throwable cause) {
if (this.cause != this)//已设置过cause,则抛异常,意思为只能设置一次
cause属性
throw new IllegalStateException("Can't overwrite cause");
if (cause == this)//若参数cause等于本身,抛异常
throw new IllegalArgumentException("Self-causation not permitted");
this.cause = cause;
return this;
}
3.打印错误信息
//遍历出错的原因轨迹
public void printStackTrace(PrintStream s) {
synchronized (s) {//输出时必须线程安全,不然别的线程也有输出的话就乱套
了
s.println(this);
StackTraceElement[] trace = getOurStackTrace();//得到异常轨技数组
for (int i=0; i < trace.length; i++)
s.println("\tat " + trace[i]);//打印每个轨迹
Throwable ourCause = getCause();//获取造成异常的起因的对象
if (ourCause != null)
ourCause.printStackTraceAsCause(s, trace);
}
}
private void printStackTraceAsCause(PrintStream s,
StackTraceElement[] causedTrace)
{
StackTraceElement[] trace = getOurStackTrace();//获得当前的异常轨迹数组
int m = trace.length-1, n = causedTrace.length-1;
//m为当前异常轨迹数组的最后一个元素的下标
//n为当前对象引起的异常的异常轨迹数组的最后一个元素的下标
while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {
m--; n--;
}
int framesInCommon = trace.length - 1 - m;//相同的数量
//打印异常轨迹
s.println("Caused by: " + this);
for (int i=0; i <= m; i++)
s.println("\tat " + trace[i]);
if (framesInCommon != 0)
s.println("\t... " + framesInCommon + " more");
// Recurse if we have a cause
Throwable ourCause = getCause();
if (ourCause != null)
ourCause.printStackTraceAsCause(s, trace);
}
public void printStackTrace(PrintWriter s) {
synchronized (s) {
s.println(this);
StackTraceElement[] trace = getOurStackTrace();
for (int i=0; i < trace.length; i++)
s.println("\tat " + trace[i]);
Throwable ourCause = getCause();
if (ourCause != null)
ourCause.printStackTraceAsCause(s, trace);
}
}
private void printStackTraceAsCause(PrintWriter s,
StackTraceElement[] causedTrace)
{
// assert Thread.holdsLock(s);
// Compute number of frames in common between this and caused
StackTraceElement[] trace = getOurStackTrace();
int m = trace.length-1, n = causedTrace.length-1;
while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {
m--; n--;
}
int framesInCommon = trace.length - 1 - m;
s.println("Caused by: " + this);
for (int i=0; i <= m; i++)
s.println("\tat " + trace[i]);
if (framesInCommon != 0)
s.println("\t... " + framesInCommon + " more");
// Recurse if we have a cause
Throwable ourCause = getCause();
if (ourCause != null)
ourCause.printStackTraceAsCause(s, trace);
}
4.fillInStackTrace
public synchronized native Throwable fillInStackTrace();//native方法获得方
法执行的栈轨迹
5.余下的一些功能
public StackTraceElement[] getStackTrace() {
return (StackTraceElement[]) getOurStackTrace().clone();
}
private synchronized StackTraceElement[] getOurStackTrace() {
//只有第一次调用才会执行if模块中的代码
if (stackTrace == null) {
int depth = getStackTraceDepth();
stackTrace = new StackTraceElement[depth];
for (int i=0; i < depth; i++)
stackTrace[i] = getStackTraceElement(i);
}
return stackTrace;
}
//设置异常的轨迹
public void setStackTrace(StackTraceElement[] stackTrace) {
StackTraceElement[] defensiveCopy =
(StackTraceElement[]) stackTrace.clone();
for (int i = 0; i < defensiveCopy.length; i++)
if (defensiveCopy[i] == null)
throw new NullPointerException("stackTrace[" + i + "]");
this.stackTrace = defensiveCopy;
}
native int getStackTraceDepth();
native StackTraceElement getStackTraceElement(int index);//获得特定下标的异
常轨迹
//序列化对象
private synchronized void writeObject(java.io.ObjectOutputStream s)
throws IOException
{
getOurStackTrace();
s.defaultWriteObject();
}