神奇的java代码,神奇的 new Exception()

原标题:神奇的 new Exception()

02f557cee2e83e9c11cf7e1db336cade.png

先看下一段代码:

publicclassMainActivityextendsAppCompatActivity{

@Override

protectedvoidonCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

test1;

}

privatevoidtest1{

test2;

}

privatevoidtest2{

test3;

}

privatevoidtest3{

test4;

}

privatevoidtest4{

Log.d( "wxl", "test", newException);

}

}

你们猜会打印什么?

12- 2912: 16: 05.4798140- 8140/com.wuxiaolong.myapplication D/wxl: test

java.lang.Exception

at com.wuxiaolong.myapplication.MainActivity.test4(MainActivity.java: 29)

at com.wuxiaolong.myapplication.MainActivity.test3(MainActivity.java: 25)

at com.wuxiaolong.myapplication.MainActivity.test2(MainActivity.java: 21)

at com.wuxiaolong.myapplication.MainActivity.test1(MainActivity.java: 17)

at com.wuxiaolong.myapplication.MainActivity.onCreate(MainActivity.java: 13)

at android.app.Activity.performCreate(Activity.java: 6975)

at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java: 1213)

at android.app.ActivityThread.performLaunchActivity(ActivityThread.java: 2770)

at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java: 2892)

at android.app.ActivityThread.-wrap11(Unknown Source: 0)

at android.app.ActivityThread$H.handleMessage(ActivityThread.java: 1593)

at android.os.Handler.dispatchMessage(Handler.java: 105)

at android.os.Looper.loop(Looper.java: 164)

at android.app.ActivityThread.main(ActivityThread.java: 6541)

at java.lang.reflect.Method.invoke(Native Method)

at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java: 240)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java: 767)

是不是有点神奇,居然把 test4 方法调用关系给打印出来了,是怎么做到的?是不是有地方把这个每步调用关系给保存下来了。

首先进 Log 看下 Log.d:

publicstaticintd(String tag, String msg, Throwable tr){

returnprintln(LOG_ID_MAIN, DEBUG, tag, msg + 'n'+ getStackTraceString(tr));

}

publicstaticString getStackTraceString(Throwable tr){

if(tr == null) {

return"";

}

// This is to reduce the amount of log spew that apps do in the non-error

// condition of the network being unavailable.

Throwable t = tr;

while(t != null) {

if(t instanceofUnknownHostException) {

return"";

}

t = t.getCause;

}

StringWriter sw = newStringWriter;

PrintWriter pw = newPrintWriter(sw);

tr.printStackTrace(pw);

pw.flush;

returnsw.toString;

}

这里第三个参数 Exception 是 Throwable 子类,初始化看 Throwable 构造方法:

publicThrowable(String message){

fillInStackTrace;

detailMessage = message;

}

/**

* Fills in the execution stack trace. This method records within this

* { @codeThrowable} object information about the current state of

* the stack frames for the current thread.

*

*

If the stack trace of this { @codeThrowable} { @linkplain

* Throwable#Throwable(String, Throwable, boolean, boolean) is not

* writable}, calling this method has no effect.

*

* @returna reference to this { @codeThrowable} instance.

* @seejava.lang.Throwable#printStackTrace

*/

publicsynchronizedThrowable fillInStackTrace{

if(stackTrace != null||

backtrace != null/* Out of protocol state */) {

backtrace = nativeFillInStackTrace;

stackTrace = libcore.util.EmptyArray.STACK_TRACE_ELEMENT;

}

returnthis;

}

如自己所想,这里 fillInStackTrace ,正是一步一步地追踪方法的调用,直到追踪到线程的终端。fillInStackTrace 是 native 方法,就不往下跟了。

Exception 表示可以被程序捕获并处理的异常错误,JVM 用方法调用栈来跟踪每个线程中一系列的方法调用过程,该栈保存了每个调用方法的本地信息。

对于独立的 Java 程序,可以一直到该程序的 main 方法,当一个新方法被调用的时候,JVM 把描述该方法的栈结构置入栈顶,位于栈顶的方法为正确执行的方法,当一个 Java 方法正常执行完毕,JVM 会从调用栈中弹处该方法的栈结构,然后继续处理前一个方法,如果 java 方法在执行代码的过程中抛出异常,JVM 必须找到能捕获异常的 catch 块代码,它首先查看当前方法是否存在这样的 catch 代码块,如果存在就执行该 catch 代码块,否则 JVM 回调用栈中弹处该方法的栈结构,继续到前一个方法中查找合适的 catch 代码块,最后如果 JVM 向上追到了 main方法,也就是一直把异常抛给了 main方法,仍然没有找到该异常处理的代码块,该线程就会异常终止,如果该线程是主线程,应用程序也随之终止,此时 JVM 将把异常直接抛给用户,在用户终端上会看到原始的异常信息。

责任编辑:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值