模塊一java虛擬機(jī)基本原理12講06jvm如何處理異常_第1頁
模塊一java虛擬機(jī)基本原理12講06jvm如何處理異常_第2頁
模塊一java虛擬機(jī)基本原理12講06jvm如何處理異常_第3頁
模塊一java虛擬機(jī)基本原理12講06jvm如何處理異常_第4頁
模塊一java虛擬機(jī)基本原理12講06jvm如何處理異常_第5頁
已閱讀5頁,還剩19頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

06|JVM 11:26 來講講Java虛擬機(jī)的異常處理。首先提醒你一下,本篇文章代碼較多,你可以點(diǎn)的轉(zhuǎn)移。隱式拋異常的主體則是Java虛擬機(jī),它指的是Java虛擬機(jī)在執(zhí)行過程中,碰到無法繼續(xù)catch代碼塊跟在ty碼塊,用來捕獲在ty塊中的某定類異常。除了所捕獲異常的類型之外,catch代碼塊還定義了針對(duì)該異常類型的異常處Jaatry代碼塊后面可以跟著多個(gè)catchJava虛擬機(jī)會(huì)從上至下匹配異常處理器。因此,前面的chfinally代碼塊:跟在try代碼塊和catch代碼塊,用來一段必定運(yùn)行的代碼。在程序正常執(zhí)行的情況下,這段代碼會(huì)在ty代碼塊運(yùn)行。否則,也就是ty發(fā)異常的情況下,如果該異常沒有獲,nay代碼塊會(huì)直接運(yùn)行,并且在運(yùn)行重新拋出該異常。如果該異常被catch代碼塊捕獲,finally代碼塊則在catch代碼塊運(yùn)行。在某些不幸的情況下,catch代碼塊也觸發(fā)了異常,那么finally代碼塊同樣會(huì)運(yùn)行,并會(huì)拋出catch代碼塊觸發(fā)的異常。在某些不幸的情況下,finally代碼塊也觸發(fā)了異常,那么只好中斷當(dāng)前finally代碼塊的執(zhí)行,并往外拋異常。上面這段聽起來有點(diǎn)繞,但是等講完Java虛擬機(jī)的異常處理機(jī)制,你便會(huì)明白這其在Java語言規(guī)范中,所有異常都是Throwable類或者其子類的實(shí)例。Throwable有兩大直接子類。第一個(gè)是Error,涵蓋程序不應(yīng)捕獲的異常。當(dāng)程序觸發(fā)Error時(shí),它的執(zhí)行狀態(tài)已經(jīng)無法恢復(fù),需要中止線程甚至是中止虛擬機(jī)。第二子類則是Exception,涵蓋程序可Exception有一個(gè)特殊的子類RuntimeException,用來表示“程序雖然無法繼續(xù)執(zhí)行,但RuntimeException和Error屬于Java里的非檢查異常(uncheckedexception)。其他異常則屬于檢查異常(checkedexception)。在Java語法中,所有的檢查異常都需要程序顯式地捕獲,或者在方法中用throws關(guān)鍵字標(biāo)注。通常情況下,程序中自定義的異常應(yīng)為檢查異常,以便最大化利用Java編譯器的編譯時(shí)檢查。異常實(shí)例的構(gòu)造十分昂貴。這是由于在構(gòu)造異常實(shí)例時(shí),Java虛擬機(jī)便需要生成該異常的stkte)。該操作會(huì)逐一當(dāng)前線程的Jaa棧幀,并且記錄下各種調(diào)試信息,包括棧幀所指向方法的名字,方法所在的類名、文件名,以及在代碼中的第幾行觸發(fā)該當(dāng)然,在生成棧軌跡時(shí),JavaJava方法(Throwable.fillInStackTrace),直接從新建異常位置開始算起。此外,Java虛擬機(jī)還會(huì)忽略標(biāo)記為不可見的Java方法棧幀。在介紹Lambda的時(shí)候會(huì)看到具體的例子。 呢?從語法角度上來看,這是允許的。然而,該異常對(duì)應(yīng)的棧軌跡并非throw語句的位 Java處理器,并且 指針、to指針、target指針以及所捕獲的異常類型構(gòu)成。這些指的值是字節(jié)碼 ytecodeindex,bci),用以定位字節(jié)碼其中,from指針和to指針標(biāo)示了該異常處理器所的范圍,例如try代碼塊所覆蓋的范圍。target指針則指向異常處理器的起始位置,例如catch代碼塊的起始位置。12publicstaticvoidmain(String[]args)3try45}catch(Exceptione)67}8}9//對(duì)應(yīng)的Javapublicstaticvoid0:invokestatic3:goto6:7:8:invokevirtual11:Exceptionfromtotarget 6Classjava/lang/Exception//舉個(gè)例子,在上圖的main方法中, 定義了一段try-catch代碼。其中,catch代碼塊所捕獲的異常類型為Exception。編譯過后,該方法的異常表擁有一個(gè)條目。其from指針和to指針分別為0和3,代表它的范圍從索引為0的字節(jié)碼開始,到索引為3的字節(jié)碼結(jié)束(不包括3)。該條目的target指針是6,代表這個(gè)異常處理器從索引為6的字節(jié)碼開始。條目的最后一列,代表該異常處理器所捕獲的異常類型正是Exception。當(dāng)程序觸發(fā)異常時(shí),Java的范圍內(nèi),Jaa虛擬機(jī)會(huì)判斷所拋出的異常和該條目想要捕獲的異常是否匹配。如果匹配,Jaa虛擬機(jī)會(huì)將控制流轉(zhuǎn)移至該條目target的字節(jié)碼。如果遍歷完所有異常表?xiàng)l目,Java虛擬機(jī)仍未匹配到異常處理器,那么它會(huì)彈出當(dāng)前方法對(duì)應(yīng)的Java棧幀,并且在調(diào)用者(caller)中重復(fù)上述操作。在情況下,Java虛擬機(jī)需要遍歷當(dāng)前線程Java棧上所有方法的異常表。finally代碼塊的編譯比較復(fù)雜。當(dāng)前版本Java編譯器的做法,是finally代碼塊的內(nèi)容,分別放在try-catch代碼塊所有正常執(zhí)行路徑以及異常執(zhí)行路徑的出口中。針對(duì)異常執(zhí)行路徑,Java編譯器會(huì)生成一個(gè)或多個(gè)異常表?xiàng)l目,整個(gè)try-catch代碼塊,并且捕獲所有種類的異常(在javap中以any指代)。這些異常表?xiàng)l目的target指針將指向另一份的finally代碼塊。并且,在這個(gè)finally代碼塊的最后,Java編譯器會(huì)重新拋如果你感的話,可以用javap工具來查看下面這段包含了try-catch-finally代碼塊的編 publicclassFooprivateintprivateintprivateintprivateint6publicvoidtest()trytryBlock=}catch(Exceptione)catchBlock=}finallyfinallyBlock= methodExit= 17$javap-cpublicvoid0:1:2: //Field5: 8:9:10:11: //Field14:15:16: //Field19: 22:23:24:25: //Field28:29:30:31:32: //Field35:36:37: //Field40:Exception totarget 58Class 可以看到,編譯結(jié)果包含三份finally代碼塊。其中,前兩份分別位于try代碼塊和catch代碼塊的正常執(zhí)行路徑出口。最后一份則作為異常處理器,try代碼塊以及catch代碼塊。它將捕獲try代碼塊觸發(fā)的、未被catch代碼塊捕獲的異常,以及catch代碼塊觸這里有一個(gè)小問題,如果catch代碼塊捕獲了異常,并且觸發(fā)了另一個(gè)異常,那么finallyJava7的SupressedJava7Supressed然而,Java層面的finally代碼塊缺少指向所捕獲異常的,所以這個(gè)新特性使用起來非為此,Java7專門構(gòu)造了一個(gè)名為try-with-resources的語法糖,在字節(jié)碼層面自動(dòng)使用Supressed異常。當(dāng)然,該語法糖的主要目的并不是使用Supressed異常,而是精簡(jiǎn)資源在Java7之前,對(duì)于打開的資源, 需要定義一個(gè)finally代碼塊,來確保該資源在正常t-y代碼塊,以保證每個(gè)資源都能夠關(guān)閉。這樣一來,代碼將會(huì)變得十分繁瑣。FileInputStreamin0=FileInputStreamin1=FileInputStreamin2=tryin0=newFileInputStream(newtryin1=newFileInputStream(newtryin2=newFileInputStream(new}finallyif(in2!=null) }finallyif(in1!=null) }finallyif(in0!=null) Java7的try-with-resources語法糖,極大地簡(jiǎn)化了上述代碼。程序可以在try關(guān)鍵字后并實(shí)例化實(shí)現(xiàn)了AutoCloseable接口的類,編譯器將自動(dòng)添加對(duì)應(yīng)的close()操作。在多個(gè)AutoCloseable實(shí)例的情況下,編譯生成的字節(jié)碼類似于上面手工編寫代碼的編譯結(jié)果。與手工代碼相比,try-with-resources還會(huì)使用Supressed異常的功能,來避publicclassFooimplementsAutoCloseableprivatefinalStringpublicFoo(Stringname){=name;4publicvoidclose()thrownew 9publicstaticvoidmain(String[]args)try(Foofoo0=newFoo("Foo0");//try-with-Foofoo1=newFoofoo2=newFoo("Foo2"))thrownew 17Exceptioninthread"main"java.lang.RuntimeException:atSuppressed:java.lang.RuntimeException:atatSuppressed:java.lang.RuntimeException:atatSuppressed:java.lang.RuntimeException:atattry-with-resources,Java7catch//在同一catchtry}catch(SomeException|OtherExceptione)6今 介紹了Java虛擬機(jī)的異常處理機(jī)制Java的異常分為Exception和Error兩種,而Exception又分為RuntimeException和其他類型。RuntimeException和Error屬于非檢查異常。其他的Exception皆屬于檢查異常,在觸發(fā)時(shí)需要顯式捕獲,或者在方法頭用throws關(guān)鍵字。Jaa字節(jié)碼中,每個(gè)方法對(duì)應(yīng)一個(gè)異常表。當(dāng)程序觸發(fā)異常時(shí),Jaa虛擬機(jī)將查找異常表,并依此決定需要將控制流轉(zhuǎn)移至哪個(gè)異常處理器之中。JavacatchnayJava7引入了Supressed異常、try-with-resources,以及多異常捕獲。后兩者屬于語法 那么今天的實(shí)踐環(huán)節(jié),你其他控制流語句與finally代碼塊之間的協(xié)作1//編譯并用javap-cpublicclassFoo4privateint5privateint6privateint7privateint89publicvoidtest()for(inti=0;i<100;i++)trytryBlock=if(i<50)}elseif(i<80)}else}}catch(Exceptione)catchBlock=}finallyfinallyBlock=}}methodExit=}} 售賣。頁面已增加防盜追蹤,將依 上一 05|JVM是如何執(zhí)行方法調(diào)用的?(下下一 【工具篇】常用工具介 79 東 throwexception估計(jì)也會(huì)影響jit 11catch里拋的異常會(huì)被finally捕獲了,再執(zhí)行完finally代碼后重新拋出該異常。由于 關(guān)于trycatch如果fortrycatch199條數(shù)據(jù)如果for里面不寫trycatch寫外面程序正常執(zhí)行但是數(shù)據(jù)返回0…三木 4 4孤獨(dú)患 2 就是checkedtrycatch,j

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論