天天看點

走進 Java 異常

前言

在寫代碼的時候用到了一點簡單的多線程,然後我用try catch語句去捕捉線程中的異常時,發現沒捕捉到。查了一下資料才發現,子線程的異常隻能被子線程本身來捕捉。然後我又回憶了一下線程,發現對異常的了解還是不是那麼透徹。于是打算寫篇文章來重新學習下異常。

only objects that are instances of this class (or one of its subclasses) are thrown by the java virtual machine or can be thrown by the java {@code throw} statement. similarly, only this class or one of its subclasses can be the argument type in a {@code catch} clause. ---《throwable源碼》

隻有該類或該類的執行個體可以被java 虛拟機或java語句抛出。相似的,也隻有這個類或該類的子類才可以做catch語句的參數類型。

for the purposes of compile-time checking of exceptions, {@codethrowable} and any subclass of {@code throwable} that is not also a  subclass of either {@link runtimeexception} or {@link error} areregarded as checked exceptions.---《throwable源碼》

throwable譯為可抛出,是所有error和exception的父類,

instances of two subclasses, {@link java.lang.error} and {@link java.lang.exception}, are conventionally used to indicate that exceptional situations have occurred. typically, these instances are freshly created in the context of the exceptional situation so as to include relevant information (such as stack trace data). ------《throwable源碼》

執行個體化error和exception類通常被用來表示意外情況的發生。典型的,這些執行個體是在意外情況下被建立的,以便包含相關資訊。比如棧軌迹資料。

上文提到了棧軌迹,這個棧該怎麼了解呢?這裡就需要一點點資料結構的知識了. 粗略的說,棧是一種具備特殊屬性的容器,先進後出。我們知道jvm的運作時資料區域被分為方法區,虛拟機棧, 本地方法棧等,不清楚區域劃分的,可以去看下我寫的這篇文章對于jvm,你就隻知道堆和棧嗎?。

那我們提出這麼一個問題, 這個java虛拟機棧和本地方法棧是用來做什麼的?

本地方法這個稱呼并不大合适,稱之為本地接口更為合适一些. 該接口不由java本身來實作,由其他語言來實作.java來調用。

java本地接口(jni)是一個程式設計架構使得運作在java虛拟機上的java程式調用或者被調用特定于本機硬體與作業系統的用其它語言(c、c++或彙編語言等)編寫的程式。

string類的intern方法就是本地方法。

哪個線程中發生

是什麼哪種類型的異常

程式在執行到哪一個方法的哪一行出現的異常。

第三部分java的設計者們将其抽象為一個類: stacktraceelement。

下面是stacktraceelement的成員變量:

這裡隻介紹: declaringclass: 方法所屬的類的全類名+方法名

stacktraceelement被虛拟機所初始化。

在程式執行發生異常時,jvm會執行個體化對應的異常類,為在執行過程中發生異常的每一個方法執行個體化一個stacktraceelement類。throwable中的getstacktraceelement() 也是一個本地方法。

首先exception和error是throwable的子類,throwable意為可抛出的.

the class exception and its subclasses are a form of throwable that indicates conditions that a reasonable application might want to catch。---《exception源碼》

exception和它的子類是可抛出的一種形式,表示這是一個設計合理的應用程式應該要處理的情況。

an {@code error} is a subclass of {@code throwable} that indicates serious problems that a reasonable application should not try to catch. most such errors are abnormal conditions.the {@code threaddeath} error, though a "normal" condition,is also a subclass of {@code error} because most applications  should not try to catch it.----《error源碼》

error則用來表示一些嚴重的問題,一個設計合理的程式不應該去處理這種狀況。大部分錯誤都是異常條件或狀況。

the  threaddeath error, though a "normal" condition,is also a subclass of  error because most applications  should not try to catch it.----《error源碼》

threaddeath類盡管是正常的狀況,但是因為大多數程式不應該試圖去捕捉它,是以它也是error的子類。

檢查異常的定義是很簡單的: exception的子類但又不是runtimeexception本身和他的子類。檢查異常必須要開發者去處理,要麼抛出,要麼去捕獲。否則編譯就不通過。比如filenotfoundexception,在使用流操縱檔案的時候,你就必須去處理它,要麼抛出,要麼捕獲。

未檢查異常: 就是runtimeexception和它的子類。

在runnable接口中去try catch

設定異常處理者,即實作uncaughtexceptionhandler接口。

當一個線程由于未捕獲異常而被中斷時,該接口的實作類将會被調用。當一個線程由于未捕獲異常而将要中斷是,虛拟機将查詢通過getuncaughtexceptionhandler來查詢該線程的異常處理者.

代碼如下: