国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - JVM如何處理異常深入詳解

JVM如何處理異常深入詳解

2021-06-28 10:17技術(shù)小黑屋 Java教程

異常處理的兩大元素:拋出異常、捕獲異常,非正常處理的兩個(gè)方法。下面這篇文章主要給大家介紹了關(guān)于JVM如何處理異常的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

無(wú)論你是使用何種編程語(yǔ)言,在日常的開發(fā)過(guò)程中,都會(huì)不可避免的要處理異常。今天本文將嘗試講解一些jvm如何處理異常問(wèn)題,希望能夠講清楚這個(gè)內(nèi)部的機(jī)制,如果對(duì)大家有所啟發(fā)和幫助,則甚好。

當(dāng)異常不僅僅是異常

我們?cè)跇?biāo)題中提到了異常,然而這里指的異常并不是單純的exception,而是更為寬泛的throwable。只是我們工作中習(xí)以為常的將它們(錯(cuò)誤地)這樣稱謂。

關(guān)于exception和throwable的關(guān)系簡(jiǎn)單描述一下

  • exception屬于throwable的子類,throwable的另一個(gè)重要的子類是error
  • throw可以拋出的都是throwable和其子類,catch可捕獲的也是throwable和其子類。

除此之外,但是exception也有一些需要我們?cè)俅螐?qiáng)調(diào)的

  • exception分為兩種類型,一種為checked exception,另一種為unchecked exception
  • checked exception,比如最常見的ioexception,這種異常需要調(diào)用處顯式處理,要么使用try catch捕獲,要么再次拋出去。
  • unchecked exception指的是所有繼承自error(包含自身)或者是runtimeexception(包含自身)的類。這些異常不強(qiáng)制在調(diào)用處進(jìn)行處理。但是也可以try catch處理。

注:本文暫不做checked exception設(shè)計(jì)的好壞的分析。

exception table 異常表

提到j(luò)vm處理異常的機(jī)制,就需要提及exception table,以下稱為異常表。我們暫且不急于介紹異常表,先看一個(gè)簡(jiǎn)單的java處理異常的小例子。

?
1
2
3
4
5
6
7
public static void simpletrycatch() {
 try {
 testnpe();
 } catch (exception e) {
 e.printstacktrace();
 }
}

上面的代碼是一個(gè)很簡(jiǎn)單的例子,用來(lái)捕獲處理一個(gè)潛在的空指針異常。

當(dāng)然如果只是看簡(jiǎn)簡(jiǎn)單單的代碼,我們很難看出什么高深之處,更沒(méi)有了今天文章要談?wù)摰膬?nèi)容。

所以這里我們需要借助一把神兵利器,它就是javap,一個(gè)用來(lái)拆解class文件的工具,和javac一樣由jdk提供。

然后我們使用javap來(lái)分析這段代碼(需要先使用javac編譯)

?
1
2
3
4
5
6
7
8
9
10
11
12
//javap -c main
 public static void simpletrycatch();
 code:
 0: invokestatic #3   // method testnpe:()v
 3: goto  11
 6: astore_0
 7: aload_0
 8: invokevirtual #5   // method java/lang/exception.printstacktrace:()v
 11: return
 exception table:
 from to target type
  0 3 6 class java/lang/exception

看到上面的代碼,應(yīng)該會(huì)有會(huì)心一笑,因?yàn)榻K于看到了exception table,也就是我們要研究的異常表。

異常表中包含了一個(gè)或多個(gè)異常處理者(exception handler)的信息,這些信息包含如下

  • from 可能發(fā)生異常的起始點(diǎn)
  • to 可能發(fā)生異常的結(jié)束點(diǎn)
  • target 上述from和to之前發(fā)生異常后的異常處理者的位置
  • type 異常處理者處理的異常的類信息

那么異常表用在什么時(shí)候呢

答案是異常發(fā)生的時(shí)候,當(dāng)一個(gè)異常發(fā)生時(shí)

1.jvm會(huì)在當(dāng)前出現(xiàn)異常的方法中,查找異常表,是否有合適的處理者來(lái)處理

2.如果當(dāng)前方法異常表不為空,并且異常符合處理者的from和to節(jié)點(diǎn),并且type也匹配,則jvm調(diào)用位于target的調(diào)用者來(lái)處理。

3.如果上一條未找到合理的處理者,則繼續(xù)查找異常表中的剩余條目

4.如果當(dāng)前方法的異常表無(wú)法處理,則向上查找(彈棧處理)剛剛調(diào)用該方法的調(diào)用處,并重復(fù)上面的操作。

5.如果所有的棧幀被彈出,仍然沒(méi)有處理,則拋給當(dāng)前的thread,thread則會(huì)終止。

6.如果當(dāng)前thread為最后一個(gè)非守護(hù)線程,且未處理異常,則會(huì)導(dǎo)致jvm終止運(yùn)行。

以上就是jvm處理異常的一些機(jī)制。

try catch -finally

除了簡(jiǎn)單的try-catch外,我們還常常和finally做結(jié)合使用。比如這樣的代碼

?
1
2
3
4
5
6
7
8
9
public static void simpletrycatchfinally() {
 try {
 testnpe();
 } catch (exception e) {
 e.printstacktrace();
 } finally {
 system.out.println("finally");
 }
}

同樣我們使用javap分析一下代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public static void simpletrycatchfinally();
 code:
 0: invokestatic #3   // method testnpe:()v
 3: getstatic #6   // field java/lang/system.out:ljava/io/printstream;
 6: ldc  #7   // string finally
 8: invokevirtual #8   // method java/io/printstream.println:(ljava/lang/string;)v
 11: goto  41
 14: astore_0
 15: aload_0
 16: invokevirtual #5   // method java/lang/exception.printstacktrace:()v
 19: getstatic #6   // field java/lang/system.out:ljava/io/printstream;
 22: ldc  #7   // string finally
 24: invokevirtual #8   // method java/io/printstream.println:(ljava/lang/string;)v
 27: goto  41
 30: astore_1
 31: getstatic #6   // field java/lang/system.out:ljava/io/printstream;
 34: ldc  #7   // string finally
 36: invokevirtual #8   // method java/io/printstream.println:(ljava/lang/string;)v
 39: aload_1
 40: athrow
 41: return
 exception table:
 from to target type
  0 3 14 class java/lang/exception
  0 3 30 any
  14 19 30 any

和之前有所不同,這次

  • 異常表中,有三條數(shù)據(jù),而我們僅僅捕獲了一個(gè)exception
  • 異常表的后兩個(gè)item的type為any

上面的三條異常表item的意思為

  • 如果0到3之間,發(fā)生了exception類型的異常,調(diào)用14位置的異常處理者。
  • 如果0到3之間,無(wú)論發(fā)生什么異常,都調(diào)用30位置的處理者
  • 如果14到19之間(即catch部分),不論發(fā)生什么異常,都調(diào)用30位置的處理者。

再次分析上面的java代碼,finally里面的部分已經(jīng)被提取到了try部分和catch部分。我們?cè)俅握{(diào)一下代碼來(lái)看一下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public static void simpletrycatchfinally();
 code:
 //try 部分提取finally代碼,如果沒(méi)有異常發(fā)生,則執(zhí)行輸出finally操作,直至goto到41位置,執(zhí)行返回操作。
 
 0: invokestatic #3   // method testnpe:()v
 3: getstatic #6   // field java/lang/system.out:ljava/io/printstream;
 6: ldc  #7   // string finally
 8: invokevirtual #8   // method java/io/printstream.println:(ljava/lang/string;)v
 11: goto  41
 
 //catch部分提取finally代碼,如果沒(méi)有異常發(fā)生,則執(zhí)行輸出finally操作,直至執(zhí)行g(shù)ot到41位置,執(zhí)行返回操作。
 14: astore_0
 15: aload_0
 16: invokevirtual #5   // method java/lang/exception.printstacktrace:()v
 19: getstatic #6   // field java/lang/system.out:ljava/io/printstream;
 22: ldc  #7   // string finally
 24: invokevirtual #8   // method java/io/printstream.println:(ljava/lang/string;)v
 27: goto  41
 //finally部分的代碼如果被調(diào)用,有可能是try部分,也有可能是catch部分發(fā)生異常。
 30: astore_1
 31: getstatic #6   // field java/lang/system.out:ljava/io/printstream;
 34: ldc  #7   // string finally
 36: invokevirtual #8   // method java/io/printstream.println:(ljava/lang/string;)v
 39: aload_1
 40: athrow //如果異常沒(méi)有被catch捕獲,而是到了這里,執(zhí)行完finally的語(yǔ)句后,仍然要把這個(gè)異常拋出去,傳遞給調(diào)用處。
 41: return

catch先后順序的問(wèn)題

我們?cè)诖a中的catch的順序決定了異常處理者在異常表的位置,所以,越是具體的異常要先處理,否則就會(huì)出現(xiàn)下面的問(wèn)題

?
1
2
3
4
5
6
7
8
9
private static void misusecatchexception() {
 try {
 testnpe();
 } catch (throwable t) {
 t.printstacktrace();
 } catch (exception e) { //error occurs during compilings with tips exception java.lang.exception has already benn caught.
 e.printstacktrace();
 }
}

這段代碼會(huì)導(dǎo)致編譯失敗,因?yàn)橄炔东@throwable后捕獲exception,會(huì)導(dǎo)致后面的catch永遠(yuǎn)無(wú)法被執(zhí)行。

return 和finally的問(wèn)題

這算是我們擴(kuò)展的一個(gè)相對(duì)比較極端的問(wèn)題,就是類似這樣的代碼,既有return,又有finally,那么finally導(dǎo)致會(huì)不會(huì)執(zhí)行

?
1
2
3
4
5
6
7
8
9
10
public static string trycatchreturn() {
 try {
 testnpe();
 return "ok";
 } catch (exception e) {
 return "error";
 } finally {
 system.out.println("trycatchreturn");
 }
}

答案是finally會(huì)執(zhí)行,那么還是使用上面的方法,我們來(lái)看一下為什么finally會(huì)執(zhí)行。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static java.lang.string trycatchreturn();
 code:
 0: invokestatic #3   // method testnpe:()v
 3: ldc  #6   // string ok
 5: astore_0
 6: getstatic #7   // field java/lang/system.out:ljava/io/printstream;
 9: ldc  #8   // string trycatchreturn
 11: invokevirtual #9   // method java/io/printstream.println:(ljava/lang/string;)v
 14: aload_0
 15: areturn 返回ok字符串,areturn意思為return a reference from a method
 16: astore_0
 17: ldc  #10   // string error
 19: astore_1
 20: getstatic #7   // field java/lang/system.out:ljava/io/printstream;
 23: ldc  #8   // string trycatchreturn
 25: invokevirtual #9   // method java/io/printstream.println:(ljava/lang/string;)v
 28: aload_1
 29: areturn //返回error字符串
 30: astore_2
 31: getstatic #7   // field java/lang/system.out:ljava/io/printstream;
 34: ldc  #8   // string trycatchreturn
 36: invokevirtual #9   // method java/io/printstream.println:(ljava/lang/string;)v
 39: aload_2
 40: athrow 如果catch有未處理的異常,拋出去。

行文倉(cāng)促,加之本人水平有限,有錯(cuò)誤的地方,請(qǐng)指出。

參考文章:

  • http://blog.jamesdbloom.com/jvminternals.html#exception_table
  • https://blog.takipi.com/the-surprising-truth-of-java-exceptions-what-is-really-going-on-under-the-hood/
  • https://en.wikipedia.org/wiki/java_bytecode_instruction_listings
  • https://dzone.com/articles/the-truth-of-java-exceptions-whats-really-going-on

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)服務(wù)器之家的支持。

原文鏈接:https://droidyue.com/blog/2018/10/21/how-jvm-handle-exceptions/

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 玖玖在线免费视频 | 一二三区字幕免费观看av | 荷兰欧美一级毛片 | 91麻豆精品国产91久久久久久久久 | 精品欧美一区二区三区久久久 | 国产成人亚洲精品 | 欧美一区亚洲一区 | 久久露脸国产精品 | 色偷偷噜噜噜亚洲男人的天堂 | 欧美一级欧美三级在线观看 | 在线观看视频黄 | 欧美精品1区2区3区 欧洲一区在线 | 中文字幕国产一区 | 国产精品久久久久久久久久久久冷 | 激情欧美一区二区三区中文字幕 | 日韩中文在线 | 日韩二区三区 | 久久精品国产久精国产 | 精品国产一二三区 | 国产乱码精品一区二区三区中文 | 在线成人免费 | 99国产精品99久久久久久 | 午夜精品视频 | 香蕉视频三级 | 欧美精品一区二区三区手机在线 | 亚洲成人高清 | 在线欧美视频 | 国产伦精品一区二区三区四区视频 | 成人午夜网 | 成人精品一区二区 | 国产二区视频 | 欧美一区二区三区视频在线观看 | 超碰人人操 | 农村少妇kkkk7777 | 天天夜夜操 | 九九久久精品 | 自拍偷拍欧美 | 国产高清不卡 | 久久在线视频 | 欧美99| 成人在线观看网 |