當前位置:首頁 » 編程語言 » java異常處理機制

java異常處理機制

發布時間: 2023-05-22 08:15:39

java異常處理的意義何在為什麼要做異常處理,作用是什麼

代替日漸衰落的error code方法的新法,提供error code所未能具體的優勢。

異常處理分離了接收和處理錯誤代碼。這個功能理清了編程者的思緒,也幫助代碼增強了可讀性,方便了維護者的閱讀和理解。


異常處理(又稱為錯誤處理)功能提供了處理程序運行時出現的任何意外或異常情況的方法。異常處理使用try、catch 和 finally關鍵字來嘗試可能未成功的操作,處理失敗,以及在事後清理資源。


(1)java異常處理機制擴展閱讀

程序設計的要求之一就是程序的健壯性。希望程序在運行時能夠不出或者少出問題。但是,在程序的實際運行時,總會有一些因素導致程序不能正常運行。

在設計演算法時,往往對演算法的正常邏輯處理流程設計得比較准確,對異常情況的處理反而不容易設計全面,導致程序在出現異常情況時崩潰。如果軟體出現這種情況會給用戶帶來極不友好的體驗。

例如:試設計一個程序,運行後提示用戶輸入兩個整數。兩個整數用空格隔開,用戶輸入後,程序顯示出兩個數字的和。這個程序正常的邏輯處理非常簡單,但普用戶輸入的兩個字元串不是整數,程序應該給出提示,否則程序有可能會崩潰。因此針對異常情況的處理也是非常重要的,當然有時這種處理會比較復雜。

② 應用技巧:Java中的異常處理

異常處理是初學者經常忽視執行的編程技巧。然而,當他們完成了一項大型項目後,就會發現僅僅停留在表面的工作是不夠的。在本文中,我們將對異常處理進行討論,並為大家解釋其重要性,尤其是要告訴大家怎樣處理這些情況。
首先,讓我們解釋一下什麼是異常情況,通常也稱例外。正如在其他的編程語言中那樣,它也適用於Java:異常情況是那些在運行時出現錯誤的情況。這些錯誤並非真正的錯誤,因為他們是一些例外。我們可以將這些情況理解為必須解決的異常事件,否則程序將無法繼續執行。所以我們就有必要了解怎樣處理異常事件。
在異常事件的例子中最顯著的應該是在程序執行時,運行時的分配變成了零。這樣程序就無法執行,於是Java就會拋出一個異常事件,確切點說是ArithmeticException。從Java程序員的角度來看,異常事件是對象。拋出異常事件類似於拋出對象。但是,並非所有的對象都可以被拋出。
為了充分理解可畢山拋出的異常事件,整個類層次結構的一些部分要消數悶被提交。主要的類稱為Throwable。這個類擁有兩個子類:Exception 和Error。一個異常事件對象應從Throwable的類中傳出。意味著它應該是Exception子類或Error子類的一個對象實例。這些都可以在 java.lang數據包中找到。
異常處理就是捕捉可能在運行時被拋出的異常事件的一項技術。Java通過try-catch-finally的異常處理語句為我們提供了強大的異常處理解決方案。而在另一方面,你也可以使用已經聲明的異常事件,如ArithmeticException, NullPointerException等。其他類擴展了Exception 類,如IOException子類。
此外,我們應該注意到異常事件包含了兩種情況:檢查過的和沒檢查的。技術上,我們認為沒檢查過的異常事件RuntimeExceptions。這些不需要在拋出的語句中作出聲明,而且對它們的捕捉也是選擇性的。不過,它們一般不會有什麼影響,如果程序員根本不能發現它們的存在。在大多數情況下,這些都是邏輯性的編程錯誤,如NullPointerException或者ArrayIndexOutOfBounds。
同時,對異常事件進行技術性檢查也迫使程序員對其進行處理和管理,意味著要對其進行單獨捕捉並覆蓋。這些都來自Exceptions類和它的子類,包括我們之前討論過的RuntimeExceptions。檢查過的異常事件要求異常事件處理因為它們有可拿彎能導致程序終止。
現在,我們對異常事件有了個基本的了解,下面就讓我們啟動集成開發環境開始編碼吧!
異常處理
前面我們提到了異常處理就是指處理代碼中的異常事件,或者在運行時向運行引擎拋出異常事件,在引擎末端它會搜索異常事件處理常式。它使用包含了一系列方法調用的調用堆棧進行搜索。
一般而言,異常事件可能因為包含一個異常活動或其他非同步異常導致的。我們討論的異常事件包括了一些基本的處理議題:怎樣捕捉和處理這些異常事件。
Java允許我們創建自己的Exception對象和類,但是會有一個關鍵的請求。這些對象和類必須是擴展的Exception類。編碼標准要求異常事件應該充分命名,意味著它們的名字就代表了其本身。
throw new Exception(「 This is an exception!」)
下面,我們看看要怎樣捕捉和處理這些異常事件。檢查以下代碼:
try{
// this is the block of code where the exception happens
// sometimes called as source/root of exception
// or even called as tricky block or tricky method

catch{Exception_Typel e) {
// dealing with this kind of exception

Catch (Exception_Type2 e) {
// dealing witn this kind of exception

//... unlimited number of catches are possible
finally {
// this block of code is always executed

try-catch-finally語句的第一個部分是嘗試阻止。這是異常事件有可能發生的部分。通常,我們建議代碼行用最小的數量來編寫,因為它們只會在異常事件發生的時候執行。這種情況發生時,執行會跳轉去捕捉那些異常事件被比較的塊中。如果它們匹配,那麼就可以處理異常事件。
不論嘗試阻止的時候,異常事件會不會發生,或不管能不能得到處理,阻止總會執行。由於它總是被執行,所以我們推薦你在這里做一些清理。因此,正如所預料的那樣,執行起來就是具有選擇性的。
Try-catch模塊的結構類似於switch-case的結構。在檢查過的需要處理的異常事件中,是有可能在相同方法中將其處理或者拋出的。後者可以通過關鍵詞拋出。在這種情況下,異常事件的種類必須在方法簽名中被指定。看這個例子:
Void myMethod () throws SomeKindOfException{
// method goes here
}
接下來,我們將為大家展示更多的異常處理實例。
初學者常常與非匹配數據類型糾纏不清。通常,它們會引發一些問題,例如,在做加法時出現非數字型代碼。下面給大家展示的代碼中,出現了異常處理的工作環境。檢查該網頁以完成嵌入式Exception種類的清單。現在,我們要處理NumberFormatException 的發生。
public static void main (String args[] ) {
double sum= 0;
for (int i=0; i﹤args. length; ++1)
try {
sum+= Double.parseDboule (args[i]);
}
Catch (NumberFormatException e) {
Ststem.out.printIn(args[i] + 「non-numeric data on」);
}
System.out.printIn(「Total sum: 「+ sum);
}
正如你所見到的,它和命令行參數一起運行,而且一旦輪到非數字型參數,它就會寫入system.out,意指出現的問題。但是項目會繼續進行,因為try模塊是循環的。否則,沒有合適的異常處理,項目就會終止。用這種方式總和還是可以計算處理並在最後顯示處理。 我們來看看另一個例子。在這個例子中,我們會要建立自己的異常實例類,該類擴展了其母Exception類。應用程序會模擬用於異常處理和拋出的堆棧機制,如堆棧是滿的或者是空的。檢查一下。
Public class StackException extends Exception {
Public StackException (String text) {
Super (text)
}
}
現在讓我們創建一個Stack類。注意push和pop方法。它們正拋出StackException,而這一動作由方法簽名導入。此外,還有一個if條件,且條件滿足時,異常事件會被拋出。否則,一切都會順利運行。
public class Stack {
private final int SIZE = 100;
private Object st[];
private int size;
private int sp;
public Stack (int size) {
if (size < MAXSIZE)
this.size = size;
else
this.size = MAXSIZE;
this.st = new Object [size];
this.sp = -1;
}
public void push (Object o) throws StackException {
if (sp == this.size - 1)
throw new StackException ("Stack is full");
this.st [++this.sp] = o;
}
public Object pop () throws StackException {
if (sp == -1)
throw new StackException ("Stack is empty");
Object o = this.st [this.sp];
this.sp--;
return o;
}
public boolean isEmpty() {
return this.sp == -1;
}
}
好的,現在是時候寫一寫Main class連同主要方法了。在這一部分,請對try-catch語句給予更多關注。有兩類異常情況可以被捕捉到。你也可以很容易地找出它們。
public class Main {
public static void main (String args[]) {
Stack s = new Stack (10);
for (int i = 0; i <= 10; ++i)
try {
s.push (new Integer(i));
}
catch (StackException e) {
System.out.println (e);
}
while (! s.isEmpty() ) {
try {
System.out.println( (Integer)(s.pop()) );
}
catch (StackException e) {
System.out.println(e);
}
}
}
}
當然,這里也會有附帶輸出。如你所見,第一行顯示出的就是異常事件,因為我們要用11個要素填補堆棧,因此,在循環到isEmpty是錯誤的時,異常事件不會拋出。
Stack is full
練習幾次以上的幾段代碼。如果異常事件被拋出但是卻能夠正確被處理那就不要感到驚訝。這就是異常處理的神奇之處。
總結
在這篇文章里我們就異常處理的實用性和重要性進行了分析。我們都知道,不管是檢查過的或是未經檢查的,程序員都要處理好異常事件,否則可能出現程序的異常終止。我們強調要將理論與實踐相結合。坦率地說,本文雖只是冰山一角,但一些基本的知識已經介紹給了大家。希望能在異常處理方面對大家有所幫助。

③ JAVA語言中,異常處理有哪幾種方式

有兩中方式:1.捕獲異常,自己處理.
2.throw出去,讓別人處理.
舉個例子:
public class A{
try{
可能放生異常的語句...

}catch(Exception e){
e.getMessage();//自己處理
}

}

public class A throws Exception{

可能放生異常的語句...

}//throw出去,讓別人處理
注意這里用的是throws
如果在方法裡面則用throw
舉例:
public class A{
try{
可能放生異常的語句...

}catch(Exception e){
e.getMessage();//自己處理
throw new Exception ("");
}

}

④ 在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錯等導致)、數組越界例外等;其它則為非運行時例外,如輸入輸出例外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 procere() {

try {

int a = 0;

int b = 42/a;

} catch(java.lang.ArithmeticException e) {

System.out.println("in procere, catch ArithmeticException: " + e);

}

}

public static void main(String args[]) {

try {

procere();

} catch(java.lang. Exception e) {

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

}

}

}

這個例子執行的結果為:

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

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

in procere, 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 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異常機制是什麼

一、異常的關鍵字:

一般來說,異常的關鍵字有:try、catch、finally、throw、throws。
網上的資料對這幾個關鍵字是這樣解釋的:
try: Opening exception-handling statement.
catch: Captures the exception.
finally: Runs its code before terminating the program.
throws: Lists the exceptions a method could throw.
Throw: Transfers control of the method to the exception handler.

try語句
try語句用大括弧{}指定了一段代碼,該段代碼可能會拋棄一個或多個例外。
catch語句
catch語句的參數類似於方法的聲明,包括一個例外類型和一個例外對象。例外類型必須為Throwable類的子類,它指明了catch語句所處理的例外類型,例外對象則由運行時系統在try所指定的代碼塊中生成並被捕獲,大括弧中包含對象的處理,其中可以調用對象的方法。
catch語句可以有多個,分別處理不同類的例外。Java運行時系統從上到下分別對每個catch語句處理的例外類型進行檢測,直到找到類型相匹配的catch語句為止。這里,類型匹配指catch所處理的例外類型與生成的例外對象的類型完全一致或者是它的父類,因此,catch語句的排列順序應該是從特殊到一般。也可以用一個catch語句處理多個例外類型,這時它的例外類型參數應該是這多個例外類型的父類,程序設計中要根據具體的情況來選擇catch語句的例外處理類型。
finally語句
try所限定的代碼中,當拋棄一個例外時,其後的代碼不會被執行。通過finally語句可以指定一塊代碼。無論try所指定的程序塊中拋棄或不拋棄例外,也無論catch語句的例外類型是否與所拋棄的例外的類型一致,finally所指定的代碼都要被執行,它提供了統一的出口。通常在finally語句中可以進行資源的清除工作。如關閉打開的文件等。
throws語句
throws總是出現在一個函數頭中,用來標明該成員函數可能拋出的各種異常。對大多數Exception子類來說,Java 編譯器會強迫你聲明在一個成員函數中拋出的異常的類型。如果異常的類型是Error或 RuntimeException, 或它們的子類,這個規則不起作用, 因為這在程序的正常部分中是不期待出現的。 如果你想明確地拋出一個RuntimeException,你必須用throws語句來聲明它的類型
throw語句
throw總是出現在函數體中,用來拋出一個異常。程序會在throw語句後立即終止,它後面的語句執行不到,然後在包含它的所有try塊中(可能在上層調用函數中)從里向外尋找含有與其匹配的catch子句的try塊。

其實,我個人覺得,簡單的來說:throws與throw從拼寫上只相差一個s,但是功能、作用上有很大的區別。throws用於在方法和類處聲明可能拋出的所有異常信息。throw而throw就是單個語句拋出異常,是指拋出的一個具體的異常類型,使用在方法(類)的內部。
如:
………………………………………………………………………………………………………
public class showUI throws Exception(){
public void tbstudy throws Exception(){
****;//
try{
/* 這里是要處理的異常 */
}
Catch(Exception of){
System.out.println(of);//列印出異常
}
}

………………………………………………………………………………………………………
throws通常不用顯示的捕獲異常,可由系統自動將所有捕獲的異常信息拋給上級方法(即調用該方法或類的所有地方);
throw則需要用戶自己捕獲相關的異常,而後再對其進行相關處理(如列印異常的地方,類型等),最後將處理後的異常信息拋出。
他們對異常處理方式也不同.throws對異常不處理,誰調用誰處理,throws的Exception的取值范圍要大於方法內部異常的最大范圍,而cathch的范圍又要大於throws的Exception的范圍;throw 主動拋出自定義異常類對象。

二、異常繼承體系

異常的繼承結構

三、java處理異常方式
在java代碼中如果發生異常,jvm(java虛擬機)會拋出異常對象,導致程序代碼中斷,這個時候jvm在做的操作就是:創建異常對象,然後拋出,比如:

1.int i= 1;
2.int j = 0;
3.int res = 0;
4.res = i/j;//除0錯誤
5.System.out.println(res);

這5句代碼運行到第四句會中斷,因為jvm拋出了異常

2.throw的作用:手動拋出異常。有時候有些錯誤在jvm看來不是錯誤,比如:
1. int age = 0;
2. age = -100;
3.System.out.println(age);
很正常的整形變數賦值,但是在我們眼中看來就不正常,誰的年齡會是負的呢?!所以我們需要自己手動引發異常,這就是throw的作用
int age = 0;
age = -100;
if(age<0){
Exception e = new Exception(); //創建異常對象
throw e; //拋出異常
}
System.out.println(age);

java中的異常機制

異常機制是指當程序出現錯誤後,程序如何處理。具體來說,異常機制提供了程序退出的安全通道。當出現錯誤後,程序執行的流程發生改變,程序的控制權轉移到異常處理器。
傳統的處理異常的辦法是,函數返回一個特殊的結果來表示出現異常(通常這個特殊結果是大家約定俗稱的),調用該函數的程序負責檢查並分析函數返回的結果。這樣做有如下的弊端:例如函數返回-1代表出現異常,但是如果函數確實要返回-1這個正確的值時就會出現混淆;可讀性降低,將程序代碼與處理異常的代碼混疊在一起;由調用函數的程序來分析錯誤,這就要求客戶程序員對庫函數有很深的了解。

在使用File類的方法時,如正在將U盤裡面的照片復制到電腦里時,有人將U盤拔掉了。這時我們的復製程序就會出錯,即拋出異常。當出現程序無法控制的外部環境問題(用戶提供的文件不存在或者創建文件時已有同名文件存在,文件內容損壞,網路不可用...)時,JAVA就會用異常對象來描述。
異常情況通常有三大類:
(1)檢查性異常:java.lang.Exception
(2)運行期異常:java.lang.RuntimeException
(3)錯誤:java.lang.Error
它們都是java.lang.Throwable類的子孫類。如右圖:
Throwable 類是 Java 語言中所有錯誤和異常類的父類,對於具體的異常,不應該使用Throwable類,而應該使用其他三者之一。
檢查性異常------程序正確,但因為外在的環境條件不滿足引發。例如:用戶錯誤及I/O問題----程序試圖打開一個並不存在的遠程Socket埠。這不是程序本身的邏輯錯誤,而很可能是遠程機器名字錯誤(用戶拼寫錯誤)。對商用軟體系統,程序開發者必須考慮並處理這個問題。JAVA編譯器強制要求處理這類異常,如果不捕獲這類異常,程序將不能被編譯。
運行期異常------這意味著程序存在bug,如數組越界,0被除,入參不滿足規范.....這類異常需要更改程序來避免,JAVA編譯器強制要求處理這類異常。用來表示設計或實現方面的問題,如數組越界等。因為設計和實現正確的程序不會引發這類異常,所以常常不處理它。發生這類異常時,運行時環境會輸出一條信息,提示用戶修正錯誤。
錯誤------一般很少見,也很難通過程序解決。它可能源於程序的bug,但一般更可能源於環境問題,如內存耗盡。錯誤在程序中無須處理,而有運行環境處理。Error表示很難恢復的錯誤,如內存越界。一般不期望用戶程序來處理,即使程序員有能力處理這種錯誤,也還是交給系統處理為好。

⑥ 簡述Java中異常處理的機制

有兩中方式:1.捕獲異常,自己處理.
2.throw出去,讓別人處理.
舉個例子:
public class A{
try{
可能發生異常的語句...

}catch(Exception e){
e.getMessage();//自己處理
}

}

public class A throws Exception{

可能發生異常的語句...

}//throw出去,讓別人處理
注意這里用的是throws
如果在方法裡面則用throw
舉例:
public class A{
try{
可能放生異常的語句...

}catch(Exception e){
e.getMessage();//自己處理
throw new Exception ("");
}

}

⑦ 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關鍵字。

熱點內容
java客戶端程序 發布:2024-05-04 08:08:11 瀏覽:939
騰訊視頻賬號和密碼哪裡看 發布:2024-05-04 08:08:11 瀏覽:451
專網數據存儲安全問題分析 發布:2024-05-04 07:33:28 瀏覽:131
如何獲得列印機無線密碼 發布:2024-05-04 06:44:59 瀏覽:418
上古諸神錄哪裡改密碼 發布:2024-05-04 06:43:55 瀏覽:263
灌籃高手手游自動蓋帽腳本 發布:2024-05-04 06:42:31 瀏覽:425
javajs引擎 發布:2024-05-04 06:37:33 瀏覽:798
javalist重復 發布:2024-05-04 06:19:27 瀏覽:511
max腳本管理 發布:2024-05-04 06:02:31 瀏覽:45
自行搭建伺服器 發布:2024-05-04 06:01:12 瀏覽:126