欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Java中自定義異常
Java 語(yǔ)言要求 java 程序中(無(wú)論是誰(shuí)寫(xiě)的代碼),所有拋出( throw )的異常都必須是從 Throwable 派生而來(lái)。 當然,實(shí)際的 Java 編程中,由于 JDK 平臺已經(jīng)為我們設計好了非常豐富和完整的異常對象分類(lèi)模型。因此, java 程序員一般是不需要再重新定義自己的異常對象。而且即便是需要擴展自定義的異常對象,也往往會(huì )從 Exception 派生而來(lái)。所以,對于 java 程序員而言,它一般只需要在它的頂級函數中 catch(Exception ex) 就可以捕獲出所有的異常對象。 所有異常對象的根基類(lèi)是 Throwable , Throwable 從 Object 直接繼承而來(lái)(這是 java 系統所強制要求的),并且它實(shí)現了 Serializable 接口(這為所有的異常對象都能夠輕松跨越 Java 組件系統做好了最充分的物質(zhì)準備)。從 Throwable 直接派生出的異常類(lèi)有 Exception 和 Error 。 Exception 是 java 程序員所最熟悉的,它一般代表了真正實(shí)際意義上的異常對象的根基類(lèi)。也即是說(shuō), Exception 和從它派生而來(lái)的所有異常都是應用程序能夠 catch 到的,并且可以進(jìn)行異常錯誤恢復處理的異常類(lèi)型。而 Error 則表示 Java 系統中出現了一個(gè)非常嚴重的異常錯誤,并且這個(gè)錯誤可能是應用程序所不能恢復的,例如 LinkageError ,或 ThreadDeath 等。
首先還是看一個(gè)例子吧!代碼如下:

import java.io.*; 
public class Trans
{
public static void main(String[] args)
{
try
{
BufferedReader rd=null;
Writer wr=null;
try
{
File srcFile = new File((args[0]));
File dstFile = new File((args[1]));
rd = new BufferedReader(new InputStreamReader(new FileInputStream(srcFile), args[2]));
wr = new OutputStreamWriter(new FileOutputStream(dstFile), args[3]);
// 注意下面這條語(yǔ)句,它有什么問(wèn)題嗎?
if (rd == null || wr == null) throw new Exception("error! test!");
while(true)
{
String sLine = rd.readLine();
if(sLine == null) break;
wr.write(sLine);
wr.write("\r\n");
}
}
finally
{
wr.flush();
wr.close();
rd.close();
}
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
}


熟悉 java 語(yǔ)言的程序員朋友們,你們認為上面的程序有什么問(wèn)題嗎?編譯能通過(guò)嗎?如果不能,那么原因又是為何呢?好了,有了自己的分析和預期之后,不妨親自動(dòng)手編譯一下上面的小程序,呵呵!結果確實(shí)如您所料?是的,的確是編譯時(shí)報錯了,錯誤信息如下:

E:\Trans.java:20: unreported exception java.lang.Exception; must be caught or declared to be thrown
if (rd == null || wr == null) throw new Exception("error! test!");
1 error


上面這種編譯錯誤信息,相信 Java 程序員肯定見(jiàn)過(guò)(可能還是屢見(jiàn)不鮮?。?!
相信老練一些的 Java 程序員一定非常清楚上述編譯出錯的原因。那就是如錯誤信息中(“ must be caught ”)描述的那樣, 在 Java 的異常處理模型中,要求所有被拋出的異常都必須要有對應的“異常處理模塊” 。也即是說(shuō),如果你在程序中 throw 出一個(gè)異常,那么在你的程序中(函數中)就必須要 catch 這個(gè)異常(處理這個(gè)異常)。例如上面的例子中,你在第 20 行代碼處,拋出了一個(gè) Exception 類(lèi)型的異常,但是在該函數中,卻沒(méi)有 catch 并處理掉此異常的地方。因此,這樣的程序即便是能夠編譯通過(guò),那么運行時(shí)也是致命的(可能導致程序的崩潰),所以, Java 語(yǔ)言干脆在編譯時(shí)就盡可能地檢查(并卡?。┻@種本不應該出現的錯誤,這無(wú)疑對提高程序的可靠性大有幫助。

但是,在 Java 語(yǔ)言中,這就是必須的。 如果一個(gè)函數中,它運行時(shí)可能會(huì )向上層調用者函數拋出一個(gè)異常,那么,它就必須在該函數的聲明中顯式的注明(采用 throws 關(guān)鍵字) 。還記得剛才那條編譯錯誤信息嗎?“ must be caught or declared to be thrown ”,其中“ must be caught ”上面已經(jīng)解釋了,而后半部分呢?“ declared to be thrown ”是指何意呢?其實(shí)指的就是“必須顯式地聲明某個(gè)函數可能會(huì )向外部拋出一個(gè)異常”,也即是說(shuō),如果一個(gè)函數內部,它可能拋出了一種類(lèi)型的異常,但該函數內部并不想(或不宜) catch 并處理這種類(lèi)型的異常,此時(shí),它就必須使用 throws 關(guān)鍵字來(lái)聲明該函數可能會(huì )向外部拋出一個(gè)異常,以便于該函數的調用者知曉并能夠及時(shí)處理這種類(lèi)型的異常。下面列出了這幾種情況的比較,代碼如下:

// 示例程序 1 ,這種寫(xiě)法能夠編譯通過(guò) 
package com.ginger.exception;
import java.io.*;
public class Trans {
        public static void main(String[] args) {
                try {
                        test();
                } catch (Exception ex) {
                        ex.printStackTrace();
                }
        }
        static void test() {
                try {
                        throw new Exception("To show Exception Successed");
                } catch (Exception ex) {
                        ex.printStackTrace();
                }
        }
}



// 示例程序 2 ,這種寫(xiě)法就不能夠編譯通過(guò) 
import java.io.*;
public class Trans {
        public static void main(String[] args) {
                try {
                        test();
                }
                // 雖然這里能夠捕獲到 Exception 類(lèi)型的異常
                catch (Exception ex) {
                        ex.printStackTrace();
                }
        }
        static void test() {
                throw new Exception("test");
        }
}



// 示例程序 3 ,這種寫(xiě)法又能夠被編譯通過(guò) 
import java.io.*;
public class Trans
{
public static void main(String[] args)
{
try
{
test();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
// 由于函數聲明了可能拋出 Exception 類(lèi)型的異常
static void test() throws Exception
{
throw new Exception("test");
}
}



// 示例程序 4 ,它又不能夠被編譯通過(guò)了 
import java.io.*;
public class Trans
{
public static void main(String[] args)
{
try
{
// 雖然 test() 函數并沒(méi)有真正拋出一個(gè) Exception 類(lèi)型的異常
// 但是由于它函數聲明時(shí),表示它可能拋出一個(gè) Exception 類(lèi)型的異常
// 所以,這里仍然不能被編譯通過(guò)。
// 呵呵!體會(huì )到了 Java 異常處理模型的嚴謹吧!
test();
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
static void test() throws Exception
{
}
}


不知上面幾個(gè)有聯(lián)系的示例是否能夠給大家帶來(lái)“豁然開(kāi)朗”的感覺(jué),坦率的說(shuō), Java 提供的異常處理模型并不復雜,相信太多太多 Java 程序員有著(zhù)比我更深刻的認識。最后,補充一種例外情況,請看如下代碼:

import java.io.*;
public class Trans {
        public static void main(String[] args) {
                try {
                        test();
                } catch (Exception ex) {
                        ex.printStackTrace();
                }
        }
        static void test() throws Error {
                throw new Error(" 故意拋出一個(gè) Error");
        }
}


朋友們!上面的程序能被編譯通過(guò)嗎?注意,按照剛才上面所總結出的規律:在 Java 的異常處理模型中,要求所有被拋出的異常都必須要有對應的 catch 塊!那么上面的程序肯定不能被編譯通過(guò),因為 Error 和 Exception 都是從 Throwable 直接派生而來(lái),而 test 函數聲明了它可能拋出 Error 類(lèi)型的異常,但在 main 函數中卻并沒(méi)有 catch(Error) 或 catch(Throwable) 塊,所以它理當是會(huì )編譯出錯的!真的嗎?不妨試試!呵呵!結果并非我們之預料,而它恰恰是正確編譯通過(guò)了。為何? WHY ? WHY ?

其實(shí),原因很簡(jiǎn)單,那就是因為 Error 異常的特殊性。 Java 異常處理模型中規定: Error 和從它派生而來(lái)的所有異常,都表示系統中出現了一個(gè)非常嚴重的異常錯誤,并且這個(gè)錯誤可能是應用程序所不能恢復的 (其實(shí)這在前面的內容中已提到過(guò))。因此,如果系統中真的出現了一個(gè) Error 類(lèi)型的異常,那么則表明,系統已處于崩潰不可恢復的狀態(tài)中,此時(shí),作為編寫(xiě) Java 應用程序的你,已經(jīng)是沒(méi)有必要(也沒(méi)能力)來(lái)處理此等異常錯誤。所以, javac 編譯器就沒(méi)有必要來(lái)保證:“在編譯時(shí),所有的 Error 異常都有其對應的錯誤處理模塊”。當然, Error 類(lèi)型的異常一般都是由系統遇到致命的錯誤時(shí)所拋出的,它最后也由 Java 虛擬機所處理。而作為 Java 程序員的你,可能永遠也不會(huì )考慮拋出一個(gè) Error 類(lèi)型的異常。因此 Error 是一個(gè)特例情況!

特別關(guān)注一下 RuntimeException
上面剛剛討論了一下 Error 類(lèi)型的異常處理情況, Java 程序員一般無(wú)須關(guān)注它(處理這種異常)。另外,其實(shí)在 Exception 類(lèi)型的異常對象中,也存在一種比較特別的“異常”類(lèi)型,那就是 RuntimeException ,雖然它是直接從 Exception 派生而來(lái),但是 Java 編譯器( javac )對 RuntimeException 卻是特殊待遇,而且是照顧有加。不信,看看下面的兩個(gè)示例吧!代碼如下:

// 示例程序 1 
// 它不能編譯通過(guò),我們可以理解
import java.io.*;

public class Trans {
        public static void main(String[] args) {
                test();
        }

        static void test() {
                // 注意這條語(yǔ)句
                throw new Exception(" 故意拋出一個(gè) Exception");
        }
}


// 示例程序 2 
// 可它卻為什么能夠編譯通過(guò)呢?
import java.io.*;

public class Trans {
        public static void main(String[] args) {
                test();
        }

        static void test() {
                // 注意這條語(yǔ)句
                throw new RuntimeException(" 故意拋出一個(gè) RuntimeException");
        }
}


對上面兩個(gè)相當類(lèi)似的程序, javac 編譯時(shí)卻遭遇了兩種截然不同的處理,按理說(shuō),第 2 個(gè)示例程序也應該像第 1 個(gè)示例程序那樣,編譯時(shí)報錯!但是 javac 編譯它時(shí),卻例外地讓它通過(guò)它,而且在運行時(shí), java 虛擬機也捕獲到了這個(gè)異常,并且會(huì )在 console 打印出詳細的異常信息。運行結果如下:

java.lang.RuntimeException: 故意拋出一個(gè) RuntimeException
at Trans.test(Trans.java:13)
at Trans.main(Trans.java:8)
Exception in thread "main"


為什么對于 RuntimeException 類(lèi)型的異常(以及從它派生而出的異常類(lèi)型), javac 和 java 虛擬機都特殊處理呢?要知道,這可是與“ Java 異常處理模型更嚴謹和更安全”的設計原則相抵觸的呀!究竟是為何呢?這簡(jiǎn)直讓人不法理解呀!

只不過(guò), Java 語(yǔ)言中, RuntimeException 被統一納入到了 Java 語(yǔ)言和 JDK 的規范之中。請看如下代碼,來(lái)驗證一下我們的理解!

import java.io.*; 
public class Trans
{
public static void main(String[] args)
{
test();
}
static void test()
{
int i = 4;
int j = 0;
// 運行時(shí),這里將觸發(fā)了一個(gè) ArithmeticException
// ArithmeticException 從 RuntimeException 派生而來(lái)
System.out.println("i / j = " + i / j);
}
}


運行結果如下:

java.lang.ArithmeticException: / by zero
at Trans.test(Trans.java:16)
at Trans.main(Trans.java:8)
Exception in thread "main"


又如下面的例子,也會(huì )產(chǎn)生一個(gè) RuntimeException ,代碼如下:

import java.io.*; 
public class Trans
{
public static void main(String[] args)
{
test();
}
static void test()
{
String str = null;
// 運行時(shí),這里將觸發(fā)了一個(gè) NullPointerException
// NullPointerException 從 RuntimeException 派生而來(lái)
str.compareTo("abc");
}
}


所以,針對 RuntimeException 類(lèi)型的異常, javac 是無(wú)法通過(guò)編譯時(shí)的靜態(tài)語(yǔ)法檢測來(lái)判斷到底哪些函數(或哪些區域的代碼)可能拋出這類(lèi)異常(這完全取決于運行時(shí)狀態(tài),或者說(shuō)運行態(tài)所決定的),也正因為如此, Java 異常處理模型中的“ must be caught or declared to be thrown ”規則也不適用于 RuntimeException (所以才有前面所提到過(guò)的奇怪編譯現象,這也屬于特殊規則吧)。但是, Java 虛擬機卻需要有效地捕獲并處理此類(lèi)異常。當然, RuntimeException 也可以被程序員顯式地拋出,而且為了程序的可靠性,對一些可能出現“運行時(shí)異常( RuntimeException )”的代碼區域,程序員最好能夠及時(shí)地處理這些意外的異常,也即通過(guò) catch(RuntimeExcetion) 或 catch(Exception) 來(lái)捕獲它們。如下面的示例程序,代碼如下:

import java.io.*; 
public class Trans
{
public static void main(String[] args)
{
try
{
test();
}
// 在上層的調用函數中,最好捕獲所有的 Exception 異常!
catch(Exception e)
{
System.out.println("go here!");
e.printStackTrace();
}
}
// 這里最好顯式地聲明一下,表明該函數可能拋出 RuntimeException
static void test() throws RuntimeException
{
String str = null;
// 運行時(shí),這里將觸發(fā)了一個(gè) NullPointerException
// NullPointerException 從 RuntimeException 派生而來(lái)
str.compareTo("abc");
}
}

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
[改善Java代碼]不要在構造函數中拋出異常
Java異常處理中throw與throws關(guān)鍵字的用法及區別
Java中主線(xiàn)程如何捕獲子線(xiàn)程拋出的異常
面試必備
Java異常分類(lèi)
Java的Exception和Error面試題10問(wèn)10答
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久