Java内のすべてのエラーと例外の親javaを解析します.lang.Throwable
10003 ワード
Java言語では、エラークラスのベースクラスはjavaです.lang.Error,異常クラスのベースクラスはjava.lang.Exception. 1)同一点:java.lang.Errorとjava.lang.Exceptionはjavaです.lang.Throwableのサブクラスなのでjava.lang.Errorとjava.lang.Exception自体とそのサブクラスは、throw new MyError()などのthrowの使用対象とすることができる.とthrow new MyException();このうち、MyErrorクラスはjava.lang.Errorのサブクラス、MyExceptionクラスはjava.lang.Exceptionのサブクラス.2)相違点:java.lang.Error自身およびそのサブクラスはtry-catch文のサポートを必要とせず、次の方法定義のようにいつでもメソッドを返すことができます.
MyErrorクラスはjavaです.lang.Errorクラスのサブクラス.java.lang.Exception自体とそのサブクラスにはtry-catch文のサポートが必要です.次の方法で定義が間違っています.
正しいメソッドの定義は次のとおりです.
ここでMyExceptionクラスはjavaです.lang.Exceptionのサブクラス.
JAVA異常はjavaプログラムの実行時に異常に遭遇して作成するオブジェクトであり、異常情報がカプセル化されている.java異常のルートクラスはjavaである.lang.Throwable、クラス全体に2つの直接サブクラスjavaがある.lang.Errorとjava.lang.Exception.Errorはプログラム自体が回復できない重大なエラーである.Exceptionは、プログラムによってキャプチャ処理可能な異常エラーを示す.JVMは、各呼び出し方法のローカル情報を保持する一連の方法呼び出しプロセスを追跡する方法呼び出しスタックを用いる.独立したJAVAプログラムについては、そのプログラムのmainメソッドに至ることができる.新しいメソッドが呼び出されると、JVMは、そのメソッドを記述するスタック構造をスタックトップに配置する、スタックトップに位置するメソッドが正しく実行されるメソッドである.JAVAメソッドが正常に実行すると、JVMは呼び出しスタックからそのメソッドのスタック構造を復元し、前のメソッドの処理を継続する.Javaメソッドがコードの実行中に異常を投げ出す場合、JVMは異常をキャプチャできるcatchブロックコードを見つけなければならない.まず、現在のメソッドにこのようなcatchコードブロックが存在するかどうかを確認し、存在する場合はそのcatchコードブロックを実行し、そうでない場合、JVMコールバック用スタックにこのメソッドのスタック構造を弾き出す、前のメソッドで適切なcatchコードブロックを検索し続ける.最後に、JVMがmain()メソッドに追いつく、すなわち、常に異常をmain()メソッドに投げつける、まだその異常処理のコードブロックが見つからない場合、そのスレッドは異常に終了し、そのスレッドがメインスレッドである場合、アプリケーションも終了する、このときJVMは異常を直接ユーザに投げつける、ユーザ端末に元の異常情報が表示される.
Java.lang.throwableソースコード解析
public String myMethod() {
throw new MyError();
}
MyErrorクラスはjavaです.lang.Errorクラスのサブクラス.java.lang.Exception自体とそのサブクラスにはtry-catch文のサポートが必要です.次の方法で定義が間違っています.
public String myMethod() {
throw new MyException();
}
正しいメソッドの定義は次のとおりです.
public String myMethod() throws MyException {
throw new MyException();
}
ここでMyExceptionクラスはjavaです.lang.Exceptionのサブクラス.
JAVA異常はjavaプログラムの実行時に異常に遭遇して作成するオブジェクトであり、異常情報がカプセル化されている.java異常のルートクラスはjavaである.lang.Throwable、クラス全体に2つの直接サブクラスjavaがある.lang.Errorとjava.lang.Exception.Errorはプログラム自体が回復できない重大なエラーである.Exceptionは、プログラムによってキャプチャ処理可能な異常エラーを示す.JVMは、各呼び出し方法のローカル情報を保持する一連の方法呼び出しプロセスを追跡する方法呼び出しスタックを用いる.独立したJAVAプログラムについては、そのプログラムのmainメソッドに至ることができる.新しいメソッドが呼び出されると、JVMは、そのメソッドを記述するスタック構造をスタックトップに配置する、スタックトップに位置するメソッドが正しく実行されるメソッドである.JAVAメソッドが正常に実行すると、JVMは呼び出しスタックからそのメソッドのスタック構造を復元し、前のメソッドの処理を継続する.Javaメソッドがコードの実行中に異常を投げ出す場合、JVMは異常をキャプチャできるcatchブロックコードを見つけなければならない.まず、現在のメソッドにこのようなcatchコードブロックが存在するかどうかを確認し、存在する場合はそのcatchコードブロックを実行し、そうでない場合、JVMコールバック用スタックにこのメソッドのスタック構造を弾き出す、前のメソッドで適切なcatchコードブロックを検索し続ける.最後に、JVMがmain()メソッドに追いつく、すなわち、常に異常をmain()メソッドに投げつける、まだその異常処理のコードブロックが見つからない場合、そのスレッドは異常に終了し、そのスレッドがメインスレッドである場合、アプリケーションも終了する、このときJVMは異常を直接ユーザに投げつける、ユーザ端末に元の異常情報が表示される.
Java.lang.throwableソースコード解析
package java.lang;
import java.io.*;
/**
*
* Throwable Error Exceptiong
* :
* Throwable()
* Throwable(String message)
* Throwable(Throwable cause)
* Throwable(String message, Throwable cause)
*
*/
public class Throwable implements Serializable {
private static final long serialVersionUID = -3042686055658047285L;
/**
* Native code saves some indication of the stack backtrace in this slot.
*/
private transient Object backtrace;
/**
*
*/
private String detailMessage;
/**
* Throwable
* null Throwable
* ,
*/
private Throwable cause = this;
/**
*
*/
private StackTraceElement[] stackTrace;
/**
* , initCause
* fillInStackTrace
*/
public Throwable() {
fillInStackTrace();
}
/**
*
*/
public Throwable(String message) {
//
fillInStackTrace();
//
detailMessage = message;
}
/**
* ,cause
*/
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);
}
/**
* ,
*/
public synchronized Throwable initCause(Throwable cause) {
//
if (this.cause != this)
throw new IllegalStateException("Can't overwrite cause");
//
if (cause == this)
throw new IllegalArgumentException("Self-causation not permitted");
//
this.cause = cause;
//
return this;
}
/**
*
*/
public String toString() {
String s = getClass().getName();
String message = getLocalizedMessage();
return (message != null) ? (s + ": " + message) : s;
}
/**
*
*/
public void printStackTrace() {
printStackTrace(System.err);
}
/**
*
*/
public void printStackTrace(PrintStream s) {
synchronized (s) {
// toString
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);
}
}
/**
*
* @param s
* @param causedTrace
*/
private void printStackTraceAsCause(PrintStream s,
StackTraceElement[] causedTrace)
{
//
StackTraceElement[] trace = getOurStackTrace();
//m ,
//n
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");
// ,
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);
}
/**
*
*/
public synchronized native Throwable fillInStackTrace();
/**
*
*/
public StackTraceElement[] getStackTrace() {
return (StackTraceElement[]) getOurStackTrace().clone();
}
/**
*
*/
private synchronized StackTraceElement[] getOurStackTrace() {
//
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;
}
/**
* ,0
*/
private native int getStackTraceDepth();
/**
*
*/
private native StackTraceElement getStackTraceElement(int index);
private synchronized void writeObject(java.io.ObjectOutputStream s)
throws IOException
{
getOurStackTrace();
s.defaultWriteObject();
}
}