日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java基础 — 异常

發(fā)布時(shí)間:2024/4/13 java 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java基础 — 异常 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

異常對象都是派生于Throwable 類的一個(gè)實(shí)例。

異常層次結(jié)構(gòu)簡化示意圖:

所有的異常都是由Throwable 繼承而來,但在下一層立即分解為兩個(gè)分支:Error 和 Exception

Error類層次結(jié)構(gòu)描述了Java運(yùn)行時(shí)系統(tǒng)的內(nèi)部錯(cuò)誤資源耗盡錯(cuò)誤

Exception 層次

Exception 層次分解為兩個(gè)分支: RuntimeException其他異常

RuntimeException 異常:

  • 錯(cuò)誤的類型轉(zhuǎn)換 ClassCastException
  • 數(shù)組訪問越界 ArrayIndexOutOfBoundsException
  • 訪問null指針 NullPointerException
  • 不是派生于 RuntimeException 異常包括:

  • 試圖在文件尾部后面讀取數(shù)據(jù)
  • 試圖打開一個(gè)不存在的文件
  • 試圖根據(jù)給定的字符串查找Class對象,而這個(gè)字符串表示的類并不存在
  • Java語言規(guī)范將派生于 Error 異常或 RuntimeException 類的所有異常稱為非受查(unchecked) 異常

    所有其他的異常稱為受查(checked)異常

    什么時(shí)候該拋出異常 throws

  • 調(diào)用一個(gè)拋出受查異常的方法
  • 運(yùn)行時(shí)發(fā)現(xiàn)錯(cuò)誤,利用 throw 語句拋出一個(gè)受查異常
  • 程序出現(xiàn)錯(cuò)誤,如 ArrayIndexOutOfBoundsException 這樣的非受查異常
  • Java 虛擬機(jī)和運(yùn)行時(shí)庫出現(xiàn)的內(nèi)部錯(cuò)誤
  • 子類方法中聲明的受查異常并不能比超類方法中聲明的異常更通用,即子類方法中可拋出更特定的異常,或者根本不拋出任何異常。特別聲明:如果超類方法沒有拋出任何受查異常,子類也不能拋出任何受查異常。

    自定義異常:

  • 定義一個(gè)派生于Exception的類,或者派生于Exception子類的類。
  • 習(xí)慣上,定義的類應(yīng)該包含兩個(gè)構(gòu)造器。一個(gè)默認(rèn)的構(gòu)造器,另一個(gè)是帶有詳細(xì)描述信息構(gòu)造器。
  • class FileFormatException extends IOException {public FileFormatException(){}public FileFormatException(String message){super(message);} } 復(fù)制代碼

    API java.lang.Throwable

    • Throwable() 構(gòu)造一個(gè)新的Throwable 對象,這個(gè)對象沒有詳細(xì)的描述信息
    • Throwable(String message) 構(gòu)造一個(gè)新的Throwable,這個(gè)對象帶有特定的詳細(xì)描述信息。習(xí)慣上,所有的派生的異常類都支持一個(gè)默認(rèn)的構(gòu)造器和一個(gè)帶有詳細(xì)信息的構(gòu)造器。
    • String getMessage() 獲得Throwable 對象的詳細(xì)描述信息

    異常處理小技巧

    一般異常處理最好的選擇,就是將異常傳遞給調(diào)用者,讓調(diào)用者自己去操心。

    在catch 字句中可以拋出一個(gè)異常,這樣做的目的是改變異常的類型。我們可以采用一種比較推薦的處理異常的方法,并且將原始異常設(shè)置為新異常的"原因":

    try {access the database } catch(SQLException e) {Throwable se = new ServletException("database error");se.initCause(e);throw se; } 復(fù)制代碼

    當(dāng)捕獲到異常時(shí),就可以使用下面這條語句重新得到原始異常:

    Throwable e = se.getCause(); 復(fù)制代碼

    使用這種包裝技術(shù),可讓用戶拋出子系統(tǒng)中的高級異常,而不會丟失原始異常的細(xì)節(jié)

    如果在一個(gè)方法中發(fā)生了一個(gè)受查異常,而不允許拋出它,那包裝技術(shù)就十分有用。我們可捕獲這個(gè)受查異常,并將它包裝成一個(gè)運(yùn)行時(shí)異常。

    finally 語句

    不管是否有異常被捕獲,finally 字句中的代碼都被執(zhí)行。

    當(dāng)finally字句包含return 語句時(shí),將會出現(xiàn)一種意想不到的結(jié)果。

    假設(shè)利用return 語句從try語句塊中退出。在方法返回前,finally字句的內(nèi)容將被執(zhí)行。如果finally字句中也有一個(gè)return語句,這個(gè)返回值將會覆蓋原始的返回值。例:

    public static int f(int n) {try{return n*n;}finally {if (2 == n)return 0;} } 復(fù)制代碼

    如果調(diào)用f(2) ,try語句返回結(jié)果為4,然而在方法返回前,要執(zhí)行finally字句。finally字句使得方法返回0。這個(gè)返回值覆蓋了原先的返回值4。所以調(diào)用 f(2) 返回的值為 0

    JAVA SE7 關(guān)閉資源的處理

    待資源的try 語句(try-with-resources) 的最簡形式

    try(Resource res = ...) {work with res } 復(fù)制代碼

    try 塊退出時(shí),會自動調(diào)用res.close()

    指定多個(gè)資源:

    try(Scanner in = new Scanner(new FileInputStream("/usr/shar/dict/words"),"UTF-8");PrintWriter out = new PrintWriter("out.txt")){while (in.hasNext())out.println(in.next().toUpperCase()); } 復(fù)制代碼

    不管這個(gè)塊如何退出,in 和 out 都會關(guān)閉。

    常規(guī)方式手動編程,就需要兩個(gè)嵌套的try/finally 語句。

    堆棧軌跡(stack trace)

    堆棧軌跡是一個(gè)方法調(diào)用過程的列表,它包含了程序執(zhí)行過程中方法調(diào)用的特定位置。

    訪問堆棧軌跡的文本描述信息

    Throwable t = new Throwable(); StackTraceElement[] frames = t.getStackTrace(); for (StackTraceElement frame : frames){analyze frame } 復(fù)制代碼

    StackTraceElement 類含有能夠獲得文件名和當(dāng)前執(zhí)行的代碼行號的方法。同時(shí),還含有能夠獲得類名和方法名的方法。

    靜態(tài)的 Thread.getAllStackTrace 方法,它可以產(chǎn)生所有線程的堆棧軌跡。例

    Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces(); for (Thread t : map.keySet()){StackTraceElement[] frames = map.get(t);analyze frames } 復(fù)制代碼

    打印一個(gè)遞歸階乘的函數(shù)的堆棧情況

    public class StackTraceTest {/*** 計(jì)算n的階乘* @param n* @return*/public static int factorial(int n){System.out.println("factorial(" + n + "):");Throwable t = new Throwable();StackTraceElement[] frames = t.getStackTrace();for (StackTraceElement f: frames)System.out.println(f);int r;if (n<=1)r =1;elser = n * factorial(n-1);System.out.println("return " + r);return r;}public static void main(String[] args){Scanner in = new Scanner(System.in);System.out.print("Enter n : ");int n = in.nextInt();factorial(n);} } 復(fù)制代碼

    計(jì)算factorial(3),打印一下內(nèi)容

    factorial(3): javabook.StackTraceTest.factorial(StackTraceTest.java:15) javabook.StackTraceTest.main(StackTraceTest.java:32) factorial(2): javabook.StackTraceTest.factorial(StackTraceTest.java:15) javabook.StackTraceTest.factorial(StackTraceTest.java:23) javabook.StackTraceTest.main(StackTraceTest.java:32) factorial(1): javabook.StackTraceTest.factorial(StackTraceTest.java:15) javabook.StackTraceTest.factorial(StackTraceTest.java:23) javabook.StackTraceTest.factorial(StackTraceTest.java:23) javabook.StackTraceTest.main(StackTraceTest.java:32) return 1 return 2 return 6 復(fù)制代碼

    使用異常小技巧

    異常處理不能代替簡單的測試

    與執(zhí)行簡單的測試相比,捕獲異常所花費(fèi)的時(shí)間大大超過前者。因此使用異常的基本規(guī)則是,旨在異常情況下使用異常機(jī)制。

    不要過分地細(xì)化異常

    將整個(gè)任務(wù)包裝在一個(gè)try塊中,這樣,當(dāng)任何一個(gè)操作出現(xiàn)問題時(shí),整個(gè)任務(wù)都可以取消。

    利用異常層次結(jié)構(gòu)

    • 不要只拋出 RuntimeException 異常。應(yīng)該尋找更加適當(dāng)?shù)淖宇惢騽?chuàng)建自己的異常類。
    • 不要只捕獲Throwable 異常,否則,會使程序代碼更難讀、更難維護(hù)
    • 考慮受查異常和非受查異常的區(qū)別。
    • 將一種異常轉(zhuǎn)換成另一種更加適合的異常時(shí)不要猶豫。

    不要壓制異常

    在java中,往往強(qiáng)化地傾向關(guān)閉異常。

    在檢測錯(cuò)誤時(shí),“苛刻”要比放任更好

    例如,當(dāng)棧空時(shí),Stack.pop 是要返回一個(gè)null,還是拋出一個(gè)異常?我們認(rèn)為:在出錯(cuò)的地方拋出一個(gè) EmptyStackException異常要比在后面拋出一個(gè) NullPointerException 異常更好。

    不要羞于傳遞異常

    讓高層次的方法通知用戶發(fā)生了錯(cuò)誤,或者放棄不成功的命令更加適宜。

    5 和 6 可以歸納為“早拋出,晚捕獲”。

    參考

    JAVA核心技術(shù)(卷1)原書第10版

    總結(jié)

    以上是生活随笔為你收集整理的Java基础 — 异常的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。