java中異常的詳解與分析處理(java異常處理總結)

本文目錄一覽:

Java異常處理機制問題

第一個輸出結果為:

exception2

finally

第二個輸出結果為:

in finally

there is an exception

異常的匹配方式是向上匹配原則,如果catch中沒有精確匹配的異常類型,即向該異常的父級異常匹配,進而處理結果。第一題中,出現了很多return混淆視聽。一般來說,finally是在return之前執行的;第二題中匹配異常時就出現了個ArithmeticException(運算異常)去匹配NullPointerException(空指針),很顯然不會匹配成功。因為他們都是RuntimeException的子類,所以捕獲ArithmeticException的代碼塊不會執行而直接執行finally中的代碼。還有,因為try中斷了代碼執行,所以在finally後面的代碼不會顯示。如果try中沒有異常發生,才會打印出outside try block。

IOException是輸入輸出的異常。一般在文件讀取操作時多發生。

===========================================

Ⅱ題詳解!

代碼執行的順序用1、2、3表示如下:

class TestException {

public static void main(String[] args) {

// step 1

try {

oneMethod(); // — goto step 2

// step 6 處理拋出的NullPointerException,在catch中匹配

} catch (Exception e) {

// step 7 NullPointerException是Excpetion的子類,故打印結果

System.out.println(“there is an exception”);

}

// 完全結束

}

static void oneMethod() {

try {

// step 2

anotherMethod(); // — goto step 3

// 因為出現了異常,所以不打印,直接匹配catch中的Exception類型

System.out.println(“normal”);

// step 4

} catch (ArithmeticException e) {

// 因為異常不匹配,所以不打印

System.out.println(“there is an arithmeticexception”);

// step 5

} finally {

// 作為try的結束操作,會執行

System.out.println(“in finally”);

}

// 因為出現了異常,所以跳出,不會打印

System.out.println(“outside try block”);

}

static void anotherMethod() {

// step 3

throw new NullPointerException();

}

}

理解了么?這個其實不難,就是一直在代碼塊之間跳轉

JAVA方法try{}..catch(Exception e){}詳解

在JAVA中由於安全性的強調

所以許多方法必須拋出異常才能在編譯的時候

不出現錯誤

解決這個問題有兩個方法一種是把代碼塊

{}

throws

Exception

另一種就是try..catch

try{}中放的是你要運行的代碼

catch(Exception

e){}中放的是如果運行代碼出現異常

要執行的部分

通常格式為catch(Exception

e){System.out.println(e)}

即輸出出現的異常

Exception

e

就是出現的異常

在java中,異常處理的機制有哪幾種,分別是什麼

1 引子

try…catch…finally恐怕是大家再熟悉不過的語句了,而且感覺用起來也是很簡單,邏輯上似乎也是很容易理解。不過,我親自體驗的「教訓」告訴我,這個東西可不是想像中的那麼簡單、聽話。不信?那你看看下面的代碼,「猜猜」它執行後的結果會是什麼?不要往後看答案、也不許執行代碼看真正答案哦。如果你的答案是正確,那麼這篇文章你就不用浪費時間看啦。

package myExample.testException;

public class TestException {

public TestException() {

}

boolean testEx() throws Exception{

boolean ret = true;

try{

ret = testEx1();

}catch (Exception e){

System.out.println(“testEx, catch exception”);

ret = false;

throw e;

}finally{

System.out.println(“testEx, finally; return value=”+ret);

return ret;

}

}

boolean testEx1() throws Exception{

boolean ret = true;

try{

ret = testEx2();

if (!ret){

return false;

}

System.out.println(“testEx1, at the end of try”);

return ret;

}catch (Exception e){

System.out.println(“testEx1, catch exception”);

ret = false;

throw e;

}

finally{

System.out.println(“testEx1, finally; return value=”+ret);

return ret;

}

}

boolean testEx2() throws Exception{

boolean ret = true;

try{

int b=12;

int c;

for (int i=2;i=-2;i–){

c=b/i;

System.out.println(“i=”+i);

}

return true;

}catch (Exception e){

System.out.println(“testEx2, catch exception”);

ret = false;

throw e;

}

finally{

System.out.println(“testEx2, finally; return value=”+ret);

return ret;

}

}

public static void main(String[] args) {

TestException testException1 = new TestException();

try{

testException1.testEx();

}catch(Exception e){

e.printStackTrace();

}

}

}

你的答案是什麼?是下面的答案嗎?

i=2

i=1

testEx2, catch exception

testEx2, finally; return value=false

testEx1, catch exception

testEx1, finally; return value=false

testEx, catch exception

testEx, finally; return value=false

如果你的答案真的如上面所說,那麼你錯啦。^_^,那就建議你仔細看一看這篇文章或者拿上面的代碼按各種不同的情況修改、執行、測試,你會發現有很多事情不是原來想像中的那麼簡單的。

現在公布正確答案:

i=2

i=1

testEx2, catch exception

testEx2, finally; return value=false

testEx1, finally; return value=false

testEx, finally; return value=false

2 基礎知識

2.1 相關概念

例外是在程序運行過程中發生的異常事件,比如除0溢出、數組越界、文件找不到等,這些事件的發生將阻止程序的正常運行。為了加強程序的魯棒性,程序設計時,必須考慮到可能發生的異常事件並做出相應的處理。C語言中,通過使用if語句來判斷是否出現了例外,同時,調用函數通過被調用函數的返回值感知在被調用函數中產生的例外事件並進行處理。全程變量ErroNo常常用來反映一個異常事件的類型。但是,這種錯誤處理機制會導致不少問題。

Java通過面向對象的方法來處理例外。在一個方法的運行過程中,如果發生了例外,則這個方法生成代表該例外的一個對象,並把它交給運行時系統,運行時系統尋找相應的代碼來處理這一例外。我們把生成例外對象並把它提交給運行時系統的過程稱為拋棄(throw)一個例外。運行時系統在方法的調用棧中查找,從生成例外的方法開始進行回朔,直到找到包含相應例外處理的方法為止,這一個過程稱為捕獲(catch)一個例外。

2.2 Throwable類及其子類

用面向對象的方法處理例外,就必須建立類的層次。類 Throwable位於這一類層次的最頂層,只有它的後代才可以做為一個例外被拋棄。圖1表示了例外處理的類層次。

從圖中可以看出,類Throwable有兩個直接子類:Error和Exception。Error類對象(如動態連接錯誤等),由Java虛擬機生成並拋棄(通常,Java程序不對這類例外進行處理);Exception類對象是Java程序處理或拋棄的對象。它有各種不同的子類分別對應於不同類型的例外。其中類RuntimeException代表運行時由Java虛擬機生成的例外,如算術運算例外ArithmeticException(由除0錯等導致)、數組越界例外ArrayIndexOutOfBoundsException等;其它則為非運行時例外,如輸入輸出例外IOException等。Java編譯器要求Java程序必須捕獲或聲明所有的非運行時例外,但對運行時例外可以不做處理。

圖1 例外處理的類層次

2.3 異常處理關鍵字

Java的異常處理是通過5個關鍵字來實現的:try,catch,throw,throws,finally。JB的在線幫助中對這幾個關鍵字是這樣解釋的:

Throws: Lists the exceptions a method could throw.

Throw: Transfers control of the method to the exception handler.

Try: Opening exception-handling statement.

Catch: Captures the exception.

Finally: Runs its code before terminating the program.

2.3.1 try語句

try語句用大括號{}指定了一段代碼,該段代碼可能會拋棄一個或多個例外。

2.3.2 catch語句

catch語句的參數類似於方法的聲明,包括一個例外類型和一個例外對象。例外類型必須為Throwable類的子類,它指明了catch語句所處理的例外類型,例外對象則由運行時系統在try所指定的代碼塊中生成並被捕獲,大括號中包含對象的處理,其中可以調用對象的方法。

catch語句可以有多個,分別處理不同類的例外。Java運行時系統從上到下分別對每個catch語句處理的例外類型進行檢測,直到找到類型相匹配的catch語句為止。這裡,類型匹配指catch所處理的例外類型與生成的例外對象的類型完全一致或者是它的父類,因此,catch語句的排列順序應該是從特殊到一般。

也可以用一個catch語句處理多個例外類型,這時它的例外類型參數應該是這多個例外類型的父類,程序設計中要根據具體的情況來選擇catch語句的例外處理類型。

2.3.3 finally語句

try所限定的代碼中,當拋棄一個例外時,其後的代碼不會被執行。通過finally語句可以指定一塊代碼。無論try所指定的程序塊中拋棄或不拋棄例外,也無論catch語句的例外類型是否與所拋棄的例外的類型一致,finally所指定的代碼都要被執行,它提供了統一的出口。通常在finally語句中可以進行資源的清除工作。如關閉打開的文件等。

2.3.4 throws語句

throws總是出現在一個函數頭中,用來標明該成員函數可能拋出的各種異常。對大多數Exception子類來說,Java 編譯器會強迫你聲明在一個成員函數中拋出的異常的類型。如果異常的類型是Error或 RuntimeException, 或它們的子類,這個規則不起作用, 因為這在程序的正常部分中是不期待出現的。 如果你想明確地拋出一個RuntimeException,你必須用throws語句來聲明它的類型。

2.3.5 throw語句

throw總是出現在函數體中,用來拋出一個異常。程序會在throw語句後立即終止,它後面的語句執行不到,然後在包含它的所有try塊中(可能在上層調用函數中)從裡向外尋找含有與其匹配的catch子句的try塊。

3 關鍵字及其中語句流程詳解

3.1 try的嵌套

你可以在一個成員函數調用的外面寫一個try語句,在這個成員函數內部,寫另一個try語句保護其他代碼。每當遇到一個try語句,異常的框架就放到堆棧上面,直到所有的try語句都完成。如果下一級的try語句沒有對某種異常進行處理,堆棧就會展開,直到遇到有處理這種異常的try語句。下面是一個try語句嵌套的例子。

class MultiNest {

static void procedure() {

try {

int a = 0;

int b = 42/a;

} catch(java.lang.ArithmeticException e) {

System.out.println(“in procedure, catch ArithmeticException: ” + e);

}

}

public static void main(String args[]) {

try {

procedure();

} catch(java.lang. Exception e) {

System.out.println(“in main, catch Exception: ” + e);

}

}

}

這個例子執行的結果為:

in procedure, catch ArithmeticException: java.lang.ArithmeticException: / by zero

成員函數procedure里有自己的try/catch控制,所以main不用去處理 ArrayIndexOutOfBoundsException;當然如果如同最開始我們做測試的例子一樣,在procedure中catch到異常時使用throw e;語句將異常拋出,那麼main當然還是能夠捕捉並處理這個procedure拋出來的異常。例如在procedure函數的catch中的System.out語句後面增加throw e;語句之後,執行結果就變為:

in procedure, catch ArithmeticException: java.lang.ArithmeticException: / by zero

in main, catch Exception: java.lang.ArithmeticException: / by zero

3.2 try-catch程序塊的執行流程以及執行結果

相對於try-catch-finally程序塊而言,try-catch的執行流程以及執行結果還是比較簡單的。

首先執行的是try語句塊中的語句,這時可能會有以下三種情況:

1. 如果try塊中所有語句正常執行完畢,那麼就不會有其他的「動做」被執行,整個try-catch程序塊正常完成。

2. 如果try語句塊在執行過程中碰到異常V,這時又分為兩種情況進行處理:

² 如果異常V能夠被與try相應的catch塊catch到,那麼第一個catch到這個異常的catch塊(也是離try最近的一個與異常V匹配的catch塊)將被執行;如果catch塊執行正常,那麼try-catch程序塊的結果就是「正常完成」;如果該catch塊由於原因R突然中止,那麼try-catch程序塊的結果就是「由於原因R突然中止(completes abruptly)」。

² 如果異常V沒有catch塊與之匹配,那麼這個try-catch程序塊的結果就是「由於拋出異常V而突然中止(completes abruptly)」。

3. 如果try由於其他原因R突然中止(completes abruptly),那麼這個try-catch程序塊的結果就是「由於原因R突然中止(completes abruptly)」。

3.3 try-catch-finally程序塊的執行流程以及執行結果

try-catch-finally程序塊的執行流程以及執行結果比較複雜。

首先執行的是try語句塊中的語句,這時可能會有以下三種情況:

1. 如果try塊中所有語句正常執行完畢,那麼finally塊的居於就會被執行,這時分為以下兩種情況:

² 如果finally塊執行順利,那麼整個try-catch-finally程序塊正常完成。

² 如果finally塊由於原因R突然中止,那麼try-catch-finally程序塊的結局是「由於原因R突然中止(completes abruptly)」

2. 如果try語句塊在執行過程中碰到異常V,這時又分為兩種情況進行處理:

² 如果異常V能夠被與try相應的catch塊catch到,那麼第一個catch到這個異常的catch塊(也是離try最近的一個與異常V匹配的catch塊)將被執行;這時就會有兩種執行結果:

² 如果catch塊執行正常,那麼finally塊將會被執行,這時分為兩種情況:

² 如果finally塊執行順利,那麼整個try-catch-finally程序塊正常完成。

² 如果finally塊由於原因R突然中止,那麼try-catch-finally程序塊的結局是「由於原因R突然中止(completes abruptly)」

² 如果catch塊由於原因R突然中止,那麼finally模塊將被執行,分為兩種情況:

² 如果如果finally塊執行順利,那麼整個try-catch-finally程序塊的結局是「由於原因R突然中止(completes abruptly)」。

² 如果finally塊由於原因S突然中止,那麼整個try-catch-finally程序塊的結局是「由於原因S突然中止(completes abruptly)」,原因R將被拋棄。

(注意,這裡就正好和我們的例子相符合,雖然我們在testEx2中使用throw e拋出了異常,但是由於testEx2中有finally塊,而finally塊的執行結果是complete abruptly的(別小看這個用得最多的return,它也是一種導致complete abruptly的原因之一啊——後文中有關於導致complete abruptly的原因分析),所以整個try-catch-finally程序塊的結果是「complete abruptly」,所以在testEx1中調用testEx2時是捕捉不到testEx1中拋出的那個異常的,而只能將finally中的return結果獲取到。

如果在你的代碼中期望通過捕捉被調用的下級函數的異常來給定返回值,那麼一定要注意你所調用的下級函數中的finally語句,它有可能會使你throw出來的異常並不能真正被上級調用函數可見的。當然這種情況是可以避免的,以testEx2為例:如果你一定要使用finally而且又要將catch中throw的e在testEx1中被捕獲到,那麼你去掉testEx2中的finally中的return就可以了。

這個事情已經在OMC2.0的MIB中出現過啦:服務器的異常不能完全被反饋到客戶端。)

² 如果異常V沒有catch塊與之匹配,那麼finally模塊將被執行,分為兩種情況:

² 如果finally塊執行順利,那麼整個try-catch-finally程序塊的結局就是「由於拋出異常V而突然中止(completes abruptly)」。

² 如果finally塊由於原因S突然中止,那麼整個try-catch-finally程序塊的結局是「由於原因S突然中止(completes abruptly)」,異常V將被拋棄。

3. 如果try由於其他原因R突然中止(completes abruptly),那麼finally塊被執行,分為兩種情況:

² 如果finally塊執行順利,那麼整個try-catch-finally程序塊的結局是「由於原因R突然中止(completes abruptly)」。

² 如果finally塊由於原因S突然中止,那麼整個try-catch-finally程序塊的結局是「由於原因S突然中止(completes abruptly)」,原因R將被拋棄。

3.4 try-catch-finally程序塊中的return

從上面的try-catch-finally程序塊的執行流程以及執行結果一節中可以看出無論try或catch中發生了什麼情況,finally都是會被執行的,那麼寫在try或者catch中的return語句也就不會真正的從該函數中跳出了,它的作用在這種情況下就變成了將控制權(語句流程)轉到finally塊中;這種情況下一定要注意返回值的處理。

例如,在try或者catch中return false了,而在finally中又return true,那麼這種情況下不要期待你的try或者catch中的return false的返回值false被上級調用函數獲取到,上級調用函數能夠獲取到的只是finally中的返回值,因為try或者catch中的return語句只是轉移控制權的作用。

3.5 如何拋出異常

如果你知道你寫的某個函數有可能拋出異常,而你又不想在這個函數中對異常進行處理,只是想把它拋出去讓調用這個函數的上級調用函數進行處理,那麼有兩種方式可供選擇:

第一種方式:直接在函數頭中throws SomeException,函數體中不需要try/catch。比如將最開始的例子中的testEx2改為下面的方式,那麼testEx1就能捕捉到testEx2拋出的異常了。

boolean testEx2() throws Exception{

boolean ret = true;

int b=12;

int c;

for (int i=2;i=-2;i–){

c=b/i;

System.out.println(“i=”+i);

}

return true;

}

第二種方式:使用try/catch,在catch中進行一定的處理之後(如果有必要的話)拋出某種異常。例如上面的testEx2改為下面的方式,testEx1也能捕獲到它拋出的異常:

boolean testEx2() throws Exception{

boolean ret = true;

try{

int b=12;

int c;

for (int i=2;i=-2;i–){

c=b/i;

System.out.println(“i=”+i);

}

return true;

}catch (Exception e){

System.out.println(“testEx2, catch exception”);

Throw e;

}

}

第三種方法:使用try/catch/finally,在catch中進行一定的處理之後(如果有必要的話)拋出某種異常。例如上面的testEx2改為下面的方式,testEx1也能捕獲到它拋出的異常:

boolean testEx2() throws Exception{

boolean ret = true;

try{

int b=12;

int c;

for (int i=2;i=-2;i–){

c=b/i;

System.out.println(“i=”+i);

throw new Exception(“aaa”);

}

return true;

}catch (java.lang.ArithmeticException e){

System.out.println(“testEx2, catch exception”);

ret = false;

throw new Exception(“aaa”);

}finally{

System.out.println(“testEx2, finally; return value=”+ret);

}

}

4 關於abrupt completion

前面提到了complete abruptly(暫且理解為「突然中止」或者「異常結束」吧),它主要包含了兩種大的情形:abrupt completion of expressions and statements,下面就分兩種情況進行解釋。

4.1 Normal and Abrupt Completion of Evaluation

每一個表達式(expression)都有一種使得其包含的計算得以一步步進行的正常模式,如果每一步計算都被執行且沒有異常拋出,那麼就稱這個表達式「正常結束(complete normally)」;如果這個表達式的計算拋出了異常,就稱為「異常結束(complete abruptly)」。異常結束通常有一個相關聯的原因(associated reason),通常也就是拋出一個異常V。

與表達式、操作符相關的運行期異常有:

² A class instance creation expression, array creation expression , or string concatenation operatior expression throws an OutOfMemoryError if there is insufficient memory available.

² An array creation expression throws a NegativeArraySizeException if the value of any dimension expression is less than zero.

² A field access throws a NullPointerException if the value of the object reference expression is null.

² A method invocation expression that invokes an instance method throws a NullPointerException if the target reference is null.

² An array access throws a NullPointerException if the value of the array reference expression is null.

² An array access throws an ArrayIndexOutOfBoundsException if the value of the array index expression is negative or greater than or equal to the length of the array.

² A cast throws a ClassCastException if a cast is found to be impermissible at run time.

² An integer division or integer remainder operator throws an ArithmeticException if the value of the right-hand operand expression is zero.

² An assignment to an array component of reference type throws an ArrayStoreException when the value to be assigned is not compatible with the component type of the array.

4.2 Normal and Abrupt Completion of Statements

正常情況我們就不多說了,在這裡主要是列出了abrupt completion的幾種情況:

² break, continue, and return 語句將導致控制權的轉換,從而使得statements不能正常地、完整地執行。

² 某些表達式的計算也可能從java虛擬機拋出異常,這些表達式在上一小節中已經總結過了;一個顯式的的throw語句也將導致異常的拋出。拋出異常也是導致控制權的轉換的原因(或者說是阻止statement正常結束的原因)。

如果上述事件發生了,那麼這些statement就有可能使得其正常情況下應該都執行的語句不能完全被執行到,那麼這些statement也就是被稱為是complete abruptly.

導致abrupt completion的幾種原因:

² A break with no label

² A break with a given label

² A continue with no label

² A continue with a given label

² A return with no value

² A return with a given value A

² throw with a given value, including exceptions thrown by the Java virtual machine

5 關於我們的編程的一點建議

弄清楚try-catch-finally的執行情況後我們才能正確使用它。

如果我們使用的是try-catch-finally語句塊,而我們又需要保證有異常時能夠拋出異常,那麼在finally語句中就不要使用return語句了(finally語句塊的最重要的作用應該是釋放申請的資源),因為finally中的return語句會導致我們的throw e被拋棄,在這個try-catch-finally的外面將只能看到finally中的返回值(除非在finally中拋出異常)。(我們需要記住:不僅throw語句是abrupt completion 的原因,return、break、continue等這些看起來很正常的語句也是導致abrupt completion的原因。)

求java學習路線圖?

/*回答內容很長,能看完的少走一個月彎路,絕不抖機靈*/

提前預警:本文適合Java新手閱讀(老手可在評論區給下建議),希望大家看完能有所收穫。

廢話不多少了,先了解一下Java零基礎入門學習路線:

第一階段:JavaSE階段

變量、數據類型、運算符

二進制和十進制的轉化

注釋、單行注釋、多行注釋、文本注釋、注釋內容和位元組碼的關係

標識符、關鍵字、駝峰原則

變量的本質、內存畫圖、變量聲明和初始化

變量的分類和作用域(局部變量、成員變量、靜態變量)

常量和Final

基本數據類型介紹

整型變量和整型常量

浮點類型、float、double

char字符型、轉義字符

boolean布爾型、if語句使用要點、布爾類型佔用空間問題

運算符介紹

算數運算符(二元、自增、自減)

賦值和賦值運算符

關係運算符詳解

邏輯運算符、短路運算符詳解

位運算符詳解

字符串連接符

條件運算符(三元運算符)

運算符優先級問題

自動類型轉換詳解

強制類型裝換詳解

基本數據類型裝換常見錯誤、溢出、L問題

使用Scanner獲取鍵盤輸入

控制語句

控制語句和實現邏輯對應

if單選結構

if_elseif_else多選結構

switch語句_IDEA更換主題

循環_while

循環_for循環_dowhile

嵌套循環

break和continue語句_標籤_控制語句底層原理

寫一個年薪計算機_百度查問題的秘訣(重要)

個人所得稅計算器軟件

方法核心詳解_天才思維模型教你高手學習思維模式

方法的重載

遞歸結構講解_遞歸頭_遞歸體

面向對象編程-基礎

面向過程和面向對象的區別

類和對象的概述

類的屬性和方法

創建對象內存分析

構造方法(Construtor)及重載

對象類型的參數傳遞

this關鍵字

static關鍵字詳解

局部代碼塊、構造代碼塊和靜態代碼塊

package和import詳解

JavaDoc生成API文檔

面向對象編程-進階

面向對象的三大特性

面向對象之【封裝(Encapsulation)】

訪問權限修飾符

面向對象之【繼承(Inheritance)】

Object類

方法重寫Override

super關鍵字詳解

重寫equals()和toString()

繼承中對象創建的內存分析

面向對象之【多態(Polymorphism)】

向上轉型

向下轉型

instanceof運算符

編譯時和運行時詳解

final修飾符

抽象類和抽象方法(abstrct)

接口的定義和實現

JDK8的接口新特性

接口應用:內部類比較器Comparable

內部類詳解

Java的內存管理與垃圾回收

異常機制

異常的概述

異常的執行過程與分析

try-catch-finally捕捉異常

throw拋出異常

throws聲明異常

異常繼承體系

運行時異常和編譯異常

自定義異常

Java常用類

Wrapper包裝類

自動裝箱和自動拆箱

包裝類的源碼分析

String類的使用與內存原理

String類的源碼分析

StringBuffer

StringBuilder

字符串處理類性能分析

Date類

System類

DateFormat類

Calendat類

Math類

BigInteger類和BigDecimal類

Random類

枚舉類

File類

常見的面試題講述與分析

數據結構算法

數據結構的概述

線性表

順序表

鏈表

棧和隊列

二叉樹

二叉查找樹

二叉平衡樹

黑紅樹

冒泡排序

選擇排序

遞歸

折半查找

集合(容器)

集合和數組的聯繫和區別

集合框架體系

ArrayList的使用和源碼分析

集合中使用泛型

LinkedList的使用和源碼分析

HashSet的使用和源碼分析

哈希表及原理

TreeSet的使用和源碼分析

比較器Comparable和Comparator

HashMap的使用和源碼分析

TreeMap的使用和源碼分析

Iterator於ListIterator

Collections工具類

舊集合類Vector、Hashtable

集合總結和選擇依據

泛型接口

泛型類

泛型方法

IO流

IO流的概念

IO流的分類及其原理分析

文件流FlieInputStream、FileOutputStream

緩衝流BufferedInputStream、BufferedOutputStream

數據流ObjectInputStream、ObjectOutputStream

序列化和反序列化

轉換流InputStreamReader、OutputStreamWriter

打印流PrintWrite和PrintStream

數組流ByteArrayOutputStream、ByteArrayInputStream

使用IO複製文件夾

多線程

進程和線程

線程的創建與啟動

創建線程的三種方式對比

線程的生命周期

線程控制

多線程的安全問題與解決辦法

線程的同步:同步代碼塊

線程的同步:同步方法

線程的同步:Lock鎖

線程的死鎖問題

線程通信

Condition

線程的完整生命周期

線程池ThreadPoolExecutor

ForkJoin框架

ThreadLocal類

網絡編程

計算機網絡基礎知識

網絡通信協議

OSI參考模型

TCP/IP參考模型

數據的封裝與拆封原理解析

TCP協議

UDP協議

IP地址和端口號

URL和Socket

使用TCP編程實現登錄功能

使用UDP編程實現客服系統

使用TCP編程實現文件上傳

集合提升尋訓練

手寫ArrayList

手寫單鏈表

手寫Linkedlist

手寫HashMap

手寫HashSet

最新並發集合類

多線程提升訓練

生產者消費者模式擴展

Lock鎖和Condition

ReadWriteLock

BlockingQueue

volatile關鍵字

多線程題目練習

JDK新特徵

面試題詳解

設計模式

設計模式入門

面向對象設計七大原則

簡單工廠模式

工廠方法模式

單例模式

原型模式

裝飾模式

適配器模式

外觀模式

第二階段:數據庫

MySQL基礎

數據庫基礎知識

MySQL基礎知識

MySQL8新特徵

安裝和卸載MySQL8

使用navicat訪問數據庫

SQL語言入門

創建數據庫表

DML

修改刪除數據庫表

表的完整性約束

表的外鍵約束

DML擴展

MySQL 查詢語句

基本select查詢

where子句

函數

group by

having

SQL99-內連接查詢

SQL99-外連接查詢

SQL99-自連接查詢

SQL92-連接查詢

不相關子查詢

相關子查詢

分頁查詢

數據庫對象

索引

事務及其特徵

事務的並發問題

事務的隔離級別

存儲過程

導入導出數據

JDBC

JDBC概述

使用JDBC完成添加/更新/刪除操作

使用JDBC完成查詢操作

JDBC常用接口

使用PreparedStatement

使用事務完成銀行轉賬

提取DBUtil工具類

使用Properties讀寫屬性文件

日誌框架log4j

開發員工管理系統

第三階段:JavaEE階段

Servlet

web開發概述

B/S和C/S架構簡介

HTTP協議

HTTP請求頭和響應頭

Tomcat安裝使用

Tomcat目錄結構

Servlet概述

Servlet快速入門

Servlet生命周期

讀取配置文件信息

HttpServletRequest

HttpServletResponse

GET和POST區別

解決中文亂碼

請求轉發與重定向

絕對路徑和相對路徑

Cookie

Session

ServletContext

ServletConfig

JSP

JSP技術介紹

JSP的執行過程

scriptlet

表達式

聲明

JSP指令元素

JSP動作元素

JSP隱式對象

JSP底層原理

九大內置對象

四個作用域

Servlet和JSP的關係和區別

MVC模式

合併Servlet

JavaScript

JavaScript概述與特點

JS基礎語法

函數

數組

Math對象

String對象

Date對象

事件event

瀏覽器開發者工具

console

DOM和BOM

window

location

navigator

history

認識DOM

DOM獲取元素

jQuery

jQuery簡介及快速入門

jQuery入口函數

jQuery對象與DOM對象互相轉換

基本選擇器

屬性選擇器

位置選擇器

表單選擇器

內容選擇器

jQuery事件

jQuery動畫效果

DOM操作-操作文本

DOM操作-操作屬性

DOM操作-操作元素

直接操作CSS樣式

操作CSS類樣式

購物車案例

表單驗證

正則表達式

EL+JSTL+過濾器+監聽器

EL介紹及使用

EL取值原理

EL隱含對象

EL邏輯運算

JSTL介紹-核心標籤庫

JSTL核心標籤庫

JSTL-格式標籤庫

Filter原理

Filter生命周期

Filter鏈

Filter登錄驗證

Filter權限控制

Listener概述及分類

Listener監聽在線用戶

Ajax和JSON

Ajax異步請求和局部刷新的原理

使用原生Ajax驗證用戶唯一性

jQuery Ajax

JSON的格式和使用

主要JSON解析器

Jackson的使用

Jackson的實現原理

使用jQuery Ajax實現三級聯動

使用jQuery Ajax實現自動補全

分頁和文件上傳/下載

分頁的意義

理解分頁工具類

實現基本分頁

實現帶查詢的分頁

文件上傳原理

文件上傳API

實現文件上傳

文件下載原理

文件下載響應頭

實現文件下載

第四階段:框架階段

MyBatis

MyBatis概述

MyBatis入門配置

基本的CRUD操作

核心配置文件詳解

Mapper.xml基礎詳解

模糊查詢

分頁的實現及插件PageHelper的使用

動態sql+sql片段的使用

一對多、多對一的關係處理

註解的使用

一級緩存和二級緩存說明及使用

generator逆向工程使用

Spring

Spring框架簡介

Spring官方壓縮包目錄介紹

Spring環境搭建

IoC/DI容器詳解

Spring創建Bean的三種方式

scope屬性講解

Spring中幾種注入方式

靜態代理設計模式

動態代理設計模式

AOP詳解

AOP中幾種通知類型

AOP兩種實現方式

自動注入

聲明式事務

事務傳播行為

事務隔離級別

只讀事務

事務回滾

基於註解式配置

常用註解

Spring 整合MyBatis

i18n

Spring整合Junit

SpringMVC

MVC架構模式

手寫MVC框架

SpringMVC簡介

SpringMVC運行原理

基於配置文件方式搭建環境

基於註解方式搭建環境

SpringMVC的跳轉及視圖解析器的配置

SpringMVC和Ajax的交互

Spring 參數注入

SpringMVC作用域傳值

視圖解析器

文件下載

文件上傳

Spring攔截器/攔截器棧

登錄狀態驗證

SpringMVC容器和Spring容器介紹

異常處理4種方式

SpringMVC5其他常用註解

Maven

Maven簡介

Maven原理

Linux安裝及注意事項

Maven項目結構

POM模型

Maven 中項目類型

創建WAR類型的Maven項目

scope屬性可取值

SSM項目拆分演示

Maven的常見插件講解

熱部署

BootStrap

BootStrap概述

BootStrap柵格系統

BootStrap常用全局CSS樣式

常用組件

常用JavaScript插件

RBAC

RBAC概述

RBAC發展歷史

基於RBAC的數據庫表設計

URL攔截實現

動態菜單實現

密碼學

第五階段:前後端分離階段

Spring Boot

Spring Boot簡介

Spring Boot實現Spring MVC

配置文件順序及類型講解

Spring Boot項目結構

Spring Boot 整合MyBatis

Spring Boot 整合Druid

Spring Boot 整合PageHelper

Spring Boot 整合logback

Spring Boot 整合JSP

Spring Boot 整合Thymeleaf

Spring Boot 開發者工具

Spring Boot 異常顯示頁面

Spring Boot 整合Junit4

Spring Boot 項目打包部署

Spring Boot 整合Quartz

Spring Boot 中Interceptor使用

Spring Boot Actuator

HikariCP

Logback

Logback簡介

Logback依賴說明

Logback 配置文件講解

Logback 控制台輸出

Logback 文件輸出

Logback 數據庫輸出

Spring Security

Spring Security簡介

Spring Security架構原理

什麼是認證和授權

基礎環境搭建

自定義認證流程

UserDetailsService和UserDetails

PasswordEncoder

自定義認證結果

授權-訪問路徑匹配方式

授權-權限管理

基於註解實現權限管理

Thymeleaf整合Security權限管理

Rememberme 實現

退出實現

CSRF

Linux – CentOS 8

Linux簡介

VMWare安裝及使用

Linux安裝及注意事項

Linux目錄結構及路徑

Linux常用命令

VMWare常用配置

XShell安裝及使用

Xftp安裝及使用

JDK解壓版配置步驟

Tomcat配置步驟

安裝MySQL

WAR包部署

Docker

Docker簡介

Docker與VM對比

Docker特點

Docker架構

Docker安裝與啟動

鏡像加速器配置

Docker鏡像操作常用命令

Docker容器操作常用命令

DockerFile

搭建本地鏡像倉庫

推送鏡像到阿里雲及本地倉庫

Docker容器生命周期

Docker數據管理

Redis

Redis簡介

Redis 單機版安裝

Redis 數據類型介紹

Redis 常用命令

Redis 持久化方案

Redis 的主從搭建

Redis的哨兵搭建

Redis 的集群搭建

Spring Boot整合Spring Data Redis

Redis的緩存穿透

Redis的緩存雪崩

Redis的緩存擊穿

Vue

vsCode和插件安裝

webpack介紹

Vue項目創建

Vue模板語法

Vue條件渲染

Vue列表渲染

Vue事件處理

Vue計算屬性

Vue Class與Style

Vue表單處理

Vue組件

Vue組件生命周期

Vue 路由配置

Vue Axios網絡請求

Vue跨域處理

Vue Element

Mock.js

Swagger

Swagger2簡介

Springfox

Swagger2基本用法

Swagger-UI用法

Swagger2配置

Swagger2常用配置

Git/GitEE

Git的下載和安裝

Git和SVN對比

Git創建版本庫

Git版本控制

Git遠程倉庫

Git分支管理

Git標籤管理

GitEE建庫

GitEE 連接及使用

GitEE 組員及管理員配置

第六階段:微服務架構

FastDFS

分佈式文件系統概述

FastDFS簡介

FastDFS架構

Tracker Server

Storage Server

FastDFS安裝

安裝帶有FastDFS模塊的Nginx

Fastdfs-java-client的使用

創建Fastdfs-java-client工具類

實現文件上傳與下載

KindEditor介紹

通過KindEditor實現文件上傳並回顯

RabbitMQ

AMQP簡介

RabbitMQ簡介

安裝Erlang

安裝RabbitMQ

RabbitMQ原理

Spring Boot 集成RabbitMQ

RabbitMQ的交換器

Spring AMQP的使用

Spring Cloud Netflix Eureka

Eureka簡介

Eureka和Zookeeper 對比

搭建Eureka註冊中心

Eureka 服務管理平台介紹

搭建高可用集群

集群原理

Eureka優雅停服

Spring Cloud Netflix Ribbon

Ribbon簡介

集中式與進程內負載均衡區別

Ribbon常見的負載均衡策略

Ribbon的點對點直連

Spring Cloud OpenFeign

Feign簡介

Feign的請求參數處理

Feign的性能優化

配置Feign負載均衡請求超時時間

Spring Cloud Netflix Hystrix

Hystrix簡介

服務降級

服務熔斷

請求緩存

Feign的雪崩處理

可視化的數據監控Hystrix-dashboard

Spring Cloud Gateway

Spring Cloud Gateway簡介

Gateway基於配置文件實現路由功能

Gateway基於配置類實現路由功能

Gateway中內置過濾器的使用

Gateway中自定義GatewayFilter過濾器的使用

Gateway中自定義GlobalFilter過濾器的使用

Gateway中使用過濾器實現鑒權

Gateway結合Hystrix實現熔斷功能

Spring Cloud Config

什麼是分佈式配置中心

創建配置中心服務端

創建配置中心客戶端

基於Gitee存儲配置文件

基於分佈式配置中心實現熱刷新

Spring Cloud Bus

什麼是消息總線

基於消息總線實現全局熱刷新

ELK

ElasticSearch介紹

ElasticSearch單機版安裝

ElasticSearch集群版安裝

ElasticSearch索引管理

ElasticSearch文檔管理

ElasticSearch文檔搜索

SpringDataElasticSearch訪問ElasticSearch

LogStash介紹

基於LogStash收集系統日誌

TX-LCN

分佈式事務簡介

分佈式事務兩大理論依據

分佈式事務常見解決方案

LCN簡介

TX-LCN的3種模式

LCN原理

LCN環境搭建及Demo演示

Nginx

Nginx的簡介

什麼是正向代理、反向代理

Nginx的安裝

Nginx配置虛擬主機

Nginx配置服務的反向代理

Nginx的負載均衡配置

Spring Session

Spring Session介紹

通過Spring Session共享session中的數據

通過Spring Session同步自定義對象

Spring Session的Redis存儲結構

設置Session失效時間

Spring Session序列化器

MyBatis Plus

MyBatis Plus簡介

Spring整合MyBatis Plus

MyBatis Plus的全局策略配置

MyBatis 的主鍵生成策略

MyBatis Plus的CRUD操作

條件構造器EntityWrapper講解

MyBatis Plus的分頁插件配置

MyBatis Plus的分頁查詢

MyBatis Plus的其他插件講解

MyBatis Plus的代碼生成器講解

MyBatis Plus的公共字段自動填充

ShardingSphere

簡介

數據庫切分方式

基本概念

MySQL主從配置

切片規則

讀寫分離

實現分庫分表

第七階段:雲服務階段

Kafka

Kafka簡介

Kafka架構

分區和日誌

Kafka單機安裝

Kafka集群配置

自定義分區

自動控制

Spring for Apache Kafka

Zookeeper

Zookeeper簡介和安裝

Zookeeper 數據模型

Zookeeper 單機版安裝

Zookeeper常見命令

ZClient操作Zookeeper

Zookeeper 集群版安裝

Zookeeper 客戶端常用命令

Zookeeper分佈式鎖

RPC

什麼是分佈式架構

什麼是RFC、RPC

HttpClient實現RPC

RestTemplate

RMI實現RPC

基於Zookeeper實現RPC 遠程過程調用

Dubbo

SOA架構介紹

Dubbo簡介

Dubbo結構圖

Dubbo註冊中心

Dubbo 支持的協議

Dubbo 註冊中心搭建

Spring Boot 整合 Dubbo

Admin管理界面

Dubbo 搭建高可用集群

Dubbo 負載均衡

Spring Cloud Alibaba Dubbo

Spring Cloud Alibaba Dubbo簡介

基於Zookeeper發佈服務

基於Zookeeper訂閱服務

實現遠程服務調用處理

Spring Cloud Alibaba Nacos

Spring Cloud Alibaba Nacos簡介

搭建Nacos服務器

基於Nacos發佈|訂閱服務

實現遠程服務調用處理

Nacos Config配置中心

Spring Cloud Alibaba Sentinel

Spring Cloud Alibaba Sentinel簡介

搭建Sentinel服務器

Sentinel-實時監控

Sentinel-簇點鏈路

Sentinel-授權規則

Sentinel-系統規則

@SentinelResource註解

持久化規則

Spring Cloud Alibaba Seata

Spring Cloud Alibaba Seata簡介

搭建Seata服務器

Seata支持的事務模式-AT模式

Seata支持的事務模式-TCC模式

Seata支持的事務模式-Saga模式

Seata支持的事務模式-XA模式

SeataAT事務模式應用方式

SeataTCC事務模式應用方式

java異常處理詳解!!

異常處理是程序設計中一個非常重要的方面,也是程序設計的一大難點,從C開始,你也許已經知道如何用if…else…來控制異常了,也許是自發的,然而這種控制異常痛苦,同一個異常或者錯誤如果多個地方出現,那麼你每個地方都要做相同處理,感覺相當的麻煩! Java語言在設計的當初就考慮到這些問題,提出異常處理的框架的方案,所有的異常都可以用一個類型來表示,不同類型的異常對應不同的子類異常(這裡的異常包括錯誤概念),定義異常處理的規範,在1.4版本以後增加了異常鏈機制,從而便於跟蹤異常!這是Java語言設計者的高明之處,也是Java語言中的一個難點,下面是我對Java異常知識的一個總結,也算是資源回收一下。

一、Java異常的基礎知識

異常是程序中的一些錯誤,但並不是所有的錯誤都是異常,並且錯誤有時候是可以避免的。比如說,你的代碼少了一個分號,那麼運行出來結果是提示是錯誤java.lang.Error;如果你用System.out.println(11/0),那麼你是因為你用0做了除數,會拋出java.lang.ArithmeticException的異常。 有些異常需要做處理,有些則不需要捕獲處理,後面會詳細講到。 天有不測風雲,人有旦夕禍福,Java的程序代碼也如此。在編程過程中,首先應當儘可能去避免錯誤和異常發生,對於不可避免、不可預測的情況則在考慮異常發生時如何處理。 Java中的異常用對象來表示。Java對異常的處理是按異常分類處理的,不同異常有不同的分類,每種異常都對應一個類型(class),每個異常都對應一個異常(類的)對象。 異常類從哪裡來?有兩個來源,一是Java語言本身定義的一些基本異常類型,二是用戶通過繼承Exception類或者其子類自己定義的異常。Exception 類及其子類是 Throwable 的一種形式,它指出了合理的應用程序想要捕獲的條件。 異常的對象從哪裡來呢?有兩個來源,一是Java運行時環境自動拋出系統生成的異常,而不管你是否願意捕獲和處理,它總要被拋出!比如除數為0的異常。二是程序員自己拋出的異常,這個異常可以是程序員自己定義的,也可以是Java語言中定義的,用throw 關鍵字拋出異常,這種異常常用來向調用者彙報異常的一些信息。 異常是針對方法來說的,拋出、聲明拋出、捕獲和處理異常都是在方法中進行的。 Java異常處理通過5個關鍵字try、catch、throw、throws、finally進行管理。基本過程是用try語句塊包住要監視的語句,如果在try語句塊內出現異常,則異常會被拋出,你的代碼在catch語句塊中可以捕獲到這個異常並做處理;還有以部分系統生成的異常在Java運行時自動拋出。你也可以通過throws關鍵字在方法上聲明該方法要拋出異常,然後在方法內部通過throw拋出異常對象。finally語句塊會在方法執行return之前執行,一般結構如下: try{ 程序代碼 }catch(異常類型1 異常的變量名1){ 程序代碼 }catch(異常類型2 異常的變量名2){ 程序代碼 }finally{ 程序代碼 } catch語句可以有多個,用來匹配多個異常,匹配上多個中一個後,執行catch語句塊時候僅僅執行匹配上的異常。catch的類型是Java語言中定義的或者程序員自己定義的,表示代碼拋出異常的類型,異常的變量名表示拋出異常的對象的引用,如果catch捕獲並匹配上了該異常,那麼就可以直接用這個異常變量名,此時該異常變量名指向所匹配的異常,並且在catch代碼塊中可以直接引用。這一點非常非常的特殊和重要! Java異常處理的目的是提高程序的健壯性,你可以在catch和finally代碼塊中給程序一個修正機會,使得程序不因異常而終止或者流程發生以外的改變。同時,通過獲取Java異常信息,也為程序的開發維護提供了方便,一般通過異常信息就很快就能找到出現異常的問題(代碼)所在。 Java異常處理是Java語言的一大特色,也是個難點,掌握異常處理可以讓寫的代碼更健壯和易於維護。

二、Java異常類類圖

下面是這幾個類的層次圖: java.lang.Object java.lang.Throwable java.lang.Exception java.lang.RuntimeException java.lang.Error java.lang.ThreadDeath

下面四個類的介紹來自java api 文檔。

1、Throwable Throwable 類是 Java 語言中所有錯誤或異常的超類。只有當對象是此類(或其子類之一)的實例時,才能通過 Java 虛擬機或者 Java throw 語句拋出。類似地,只有此類或其子類之一才可以是 catch 子句中的參數類型。 兩個子類的實例,Error 和 Exception,通常用於指示發生了異常情況。通常,這些實例是在異常情況的上下文中新近創建的,因此包含了相關的信息(比如堆棧跟蹤數據)。

2、Exception Exception 類及其子類是 Throwable 的一種形式,它指出了合理的應用程序想要捕獲的條件,表示程序本身可以處理的異常。

3、Error Error 是 Throwable 的子類,表示僅靠程序本身無法恢復的嚴重錯誤,用於指示合理的應用程序不應該試圖捕獲的嚴重問題。 在執行該方法期間,無需在方法中通過throws聲明可能拋出但沒有捕獲的 Error 的任何子類,因為Java編譯器不去檢查它,也就是說,當程序中可能出現這類異常時,即使沒有用try…catch語句捕獲它,也沒有用throws字句聲明拋出它,還是會編譯通過。

4、RuntimeException RuntimeException 是那些可能在 Java 虛擬機正常運行期間拋出的異常的超類。Java編譯器不去檢查它,也就是說,當程序中可能出現這類異常時,即使沒有用try…catch語句捕獲它,也沒有用throws字句聲明拋出它,還是會編譯通過,這種異常可以通過改進代碼實現來避免。

5、ThreadDeath 調用 Thread 類中帶有零參數的 stop 方法時,受害線程將拋出一個 ThreadDeath 實例。 僅當應用程序在被異步終止後必須清除時才應該捕獲這個類的實例。如果 ThreadDeath 被一個方法捕獲,那麼將它重新拋出非常重要,因為這樣才能讓該線程真正終止。 如果沒有捕獲 ThreadDeath,則頂級錯誤處理程序不會輸出消息。 雖然 ThreadDeath 類是「正常出現」的,但它只能是 Error 的子類而不是 Exception 的子類,因為許多應用程序捕獲所有出現的 Exception,然後又將其放棄。

以上是對有關異常API的一個簡單介紹,用法都很簡單,關鍵在於理解異常處理的原理,具體用法參看Java API文檔。

三、Java異常處理機制

對於可能出現異常的代碼,有兩種處理辦法: 第一、在方法中用try…catch語句捕獲並處理異常,catach語句可以有多個,用來匹配多個異常。例如: public void p(int x){ try{ … }catch(Exception e){ … }finally{ … } }

第二、對於處理不了的異常或者要轉型的異常,在方法的聲明處通過throws語句拋出異常。例如: public void test1() throws MyException{ … if(….){ throw new MyException(); } } 如果每個方法都是簡單的拋出異常,那麼在方法調用方法的多層嵌套調用中,Java虛擬機會從出現異常的方法代碼塊中往回找,直到找到處理該異常的代碼塊為止。然後將異常交給相應的catch語句處理。如果Java虛擬機追溯到方法調用棧最底部main()方法時,如果仍然沒有找到處理異常的代碼塊,將按照下面的步驟處理: 第一、調用異常的對象的printStackTrace()方法,打印方法調用棧的異常信息。 第二、如果出現異常的線程為主線程,則整個程序運行終止;如果非主線程,則終止該線程,其他線程繼續運行。 通過分析思考可以看出,越早處理異常消耗的資源和時間越小,產生影響的範圍也越小。因此,不要把自己能處理的異常也拋給調用者。 還有一點,不可忽視:finally語句在任何情況下都必須執行的代碼,這樣可以保證一些在任何情況下都必須執行代碼的可靠性。比如,在數據庫查詢異常的時候,應該釋放JDBC連接等等。finally語句先於return語句執行,而不論其先後位置,也不管是否try塊出現異常。finally語句唯一不被執行的情況是方法執行了System.exit()方法。System.exit()的作用是終止當前正在運行的 Java 虛擬機。finally語句塊中不能通過給變量賦新值來改變return的返回值,也建議不要在finally塊中使用return語句,沒有意義還容易導致錯誤。

最後還應該注意一下異常處理的語法規則: 第一、try語句不能單獨存在,可以和catch、finally組成 try…catch…finally、try…catch、try…finally三種結構,catch語句可以有一個或多個,finally語句最多一個,try、catch、finally這三個關鍵字均不能單獨使用。 第二、try、catch、finally三個代碼塊中變量的作用域分別獨立而不能相互訪問。如果要在三個塊中都可以訪問,則需要將變量定義到這些塊的外面。 第三、多個catch塊時候,Java虛擬機會匹配其中一個異常類或其子類,就執行這個catch塊,而不會再執行別的catch塊。 第四、throw語句後不允許有緊跟其他語句,因為這些沒有機會執行。 第五、如果一個方法調用了另外一個聲明拋出異常的方法,那麼這個方法要麼處理異常,要麼聲明拋出。

那怎麼判斷一個方法可能會出現異常呢?一般來說,方法聲明的時候用了throws語句,方法中有throw語句,方法調用的方法聲明有throws關鍵字。

throw和throws關鍵字的區別 throw用來拋出一個異常,在方法體內。語法格式為:throw 異常對象。 throws用來聲明方法可能會拋出什麼異常,在方法名後,語法格式為:throws 異常類型1,異常類型2…異常類型n。

四、如何定義和使用異常類

1、使用已有的異常類,假如為IOException、SQLException。 try{ 程序代碼 }catch(IOException ioe){ 程序代碼 }catch(SQLException sqle){ 程序代碼 }finally{ 程序代碼 }

2、自定義異常類 創建Exception或者RuntimeException的子類即可得到一個自定義的異常類。例如: public class MyException extends Exception{ public MyException(){} public MyException(String smg){ super(smg); } }

3、使用自定義的異常 用throws聲明方法可能拋出自定義的異常,並用throw語句在適當的地方拋出自定義的異常。例如: 在某種條件拋出異常 public void test1() throws MyException{ … if(….){ throw new MyException(); } }

將異常轉型(也叫轉譯),使得異常更易讀易於理解 public void test2() throws MyException{ … try{ … }catch(SQLException e){ … throw new MyException(); } }

還有一個代碼,很有意思: public void test2() throws MyException{ … try { … } catch (MyException e) { throw e; } }

這段代碼實際上捕獲了異常,然後又和盤托出,沒有一點意義,如果這樣還有什麼好處理的,不處理就行了,直接在方法前用throws聲明拋出不就得了。異常的捕獲就要做一些有意義的處理。

五、運行時異常和受檢查異常

Exception類可以分為兩種:運行時異常和受檢查異常。 1、運行時異常 RuntimeException類及其子類都被稱為運行時異常,這種異常的特點是Java編譯器不去檢查它,也就是說,當程序中可能出現這類異常時,即使沒有用try…catch語句捕獲它,也沒有用throws字句聲明拋出它,還是會編譯通過。例如,當除數為零時,就會拋出java.lang.ArithmeticException異常。 2、受檢查異常 除了RuntimeException類及其子類外,其他的Exception類及其子類都屬於受檢查異常,這種異常的特點是要麼用try…catch捕獲處理,要麼用throws語句聲明拋出,否則編譯不會通過。 3、兩者的區別 運行時異常表示無法讓程序恢復運行的異常,導致這種異常的原因通常是由於執行了錯誤的操作。一旦出現錯誤,建議讓程序終止。 受檢查異常表示程序可以處理的異常。如果拋出異常的方法本身不處理或者不能處理它,那麼方法的調用者就必須去處理該異常,否則調用會出錯,連編譯也無法通過。當然,這兩種異常都是可以通過程序來捕獲並處理的,比如除數為零的運行時異常: public class HelloWorld { public static void main(String[] args) { System.out.println(“Hello World!!!”); try{ System.out.println(1/0); }catch(ArithmeticException e){ System.out.println(“除數為0!”); } System.out.println(“除數為零後程序沒有終止啊,呵呵!!!”); } }

運行結果:

Hello World!!! 除數為0! 除數為零後程序沒有終止啊,呵呵!!!

4、運行時錯誤 Error類及其子類表示運行時錯誤,通常是由Java虛擬機拋出的,JDK中與定義了一些錯誤類,比如VirtualMachineError 和OutOfMemoryError,程序本身無法修復這些錯誤.一般不去擴展Error類來創建用戶自定義的錯誤類。而RuntimeException類表示程序代碼中的錯誤,是可擴展的,用戶可以創建特定運行時異常類。 Error(運行時錯誤)和運行時異常的相同之處是:Java編譯器都不去檢查它們,當程序運行時出現它們,都會終止運行。

5、最佳解決方案 對於運行時異常,我們不要用try…catch來捕獲處理,而是在程序開發調試階段,盡量去避免這種異常,一旦發現該異常,正確的做法就會改進程序設計的代碼和實現方式,修改程序中的錯誤,從而避免這種異常。捕獲並處理運行時異常是好的解決辦法,因為可以通過改進代碼實現來避免該種異常的發生。 對於受檢查異常,沒說的,老老實實去按照異常處理的方法去處理,要麼用try…catch捕獲並解決,要麼用throws拋出! 對於Error(運行時錯誤),不需要在程序中做任何處理,出現問題後,應該在程序在外的地方找問題,然後解決。

六、異常轉型和異常鏈 異常轉型在上面已經提到過了,實際上就是捕獲到異常後,將異常以新的類型的異常再拋出,這樣做一般為了異常的信息更直觀!比如: public void run() throws MyException{ … try{ … }catch(IOException e){ … throw new MyException(); }finally{ … } }

異常鏈,在JDK1.4以後版本中,Throwable類支持異常鏈機制。Throwable 包含了其線程創建時線程執行堆棧的快照。它還包含了給出有關錯誤更多信息的消息字符串。最後,它還可以包含 cause(原因):另一個導致此 throwable 拋出的 throwable。它也稱為異常鏈 設施,因為 cause 自身也會有 cause,依此類推,就形成了異常鏈,每個異常都是由另一個異常引起的。 通俗的說,異常鏈就是把原始的異常包裝為新的異常類,並在新的異常類中封裝了原始異常類,這樣做的目的在於找到異常的根本原因。

通過Throwable的兩個構造方法可以創建自定義的包含異常原因的異常類型: Throwable(String message, Throwable cause) 構造一個帶指定詳細消息和 cause 的新 throwable。 Throwable(Throwable cause) 構造一個帶指定 cause 和 (cause==null ? null :cause.toString())(它通常包含類和 cause 的詳細消息)的詳細消息的新 throwable。 getCause() 返回此 throwable 的 cause;如果 cause 不存在或未知,則返回 null。 initCause(Throwable cause) 將此 throwable 的 cause 初始化為指定值。 在Throwable的子類Exception中,也有類似的指定異常原因的構造方法: Exception(String message, Throwable cause) 構造帶指定詳細消息和原因的新異常。 Exception(Throwable cause) 根據指定的原因和 (cause==null ? null : cause.toString()) 的詳細消息構造新異常(它通常包含 cause 的類和詳細消息)。 因此,可以通過擴展Exception類來構造帶有異常原因的新的異常類。

七、Java異常處理的原則和技巧

1、避免過大的try塊,不要把不會出現異常的代碼放到try塊裏面,盡量保持一個try塊對應一個或多個異常。 2、細化異常的類型,不要不管什麼類型的異常都寫成Excetpion。 3、catch塊盡量保持一個塊捕獲一類異常,不要忽略捕獲的異常,捕獲到後要麼處理,要麼轉譯,要麼重新拋出新類型的異常。 4、不要把自己能處理的異常拋給別人。 5、不要用try…catch參與控制程序流程,異常控制的根本目的是處理程序的非正常情況。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/152957.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-13 06:08
下一篇 2024-11-13 06:08

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Bean加載過程

    Java Bean加載過程涉及到類加載器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean加載的過程。 一、類加載器 類加載器是Java虛擬機…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發佈。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字符串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字符串中是否存在多個指定字符: 一、字符串遍歷 字符串是Java編程中非常重要的一種數據類型。要判斷字符串中是否存在多個指定字符…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29
  • Java 8 Group By 會影響排序嗎?

    是的,Java 8中的Group By會對排序產生影響。本文將從多個方面探討Group By對排序的影響。 一、Group By的概述 Group By是SQL中的一種常見操作,它…

    編程 2025-04-29

發表回復

登錄後才能評論