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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java基础 — 异常

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

異常對象都是派生于Throwable 類的一個實例。

異常層次結構簡化示意圖:

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

Error類層次結構描述了Java運行時系統的內部錯誤資源耗盡錯誤

Exception 層次

Exception 層次分解為兩個分支: RuntimeException其他異常

RuntimeException 異常:

  • 錯誤的類型轉換 ClassCastException
  • 數組訪問越界 ArrayIndexOutOfBoundsException
  • 訪問null指針 NullPointerException
  • 不是派生于 RuntimeException 異常包括:

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

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

    什么時候該拋出異常 throws

  • 調用一個拋出受查異常的方法
  • 運行時發現錯誤,利用 throw 語句拋出一個受查異常
  • 程序出現錯誤,如 ArrayIndexOutOfBoundsException 這樣的非受查異常
  • Java 虛擬機和運行時庫出現的內部錯誤
  • 子類方法中聲明的受查異常并不能比超類方法中聲明的異常更通用,即子類方法中可拋出更特定的異常,或者根本不拋出任何異常。特別聲明:如果超類方法沒有拋出任何受查異常,子類也不能拋出任何受查異常。

    自定義異常:

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

    API java.lang.Throwable

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

    異常處理小技巧

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

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

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

    當捕獲到異常時,就可以使用下面這條語句重新得到原始異常:

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

    使用這種包裝技術,可讓用戶拋出子系統中的高級異常,而不會丟失原始異常的細節

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

    finally 語句

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

    當finally字句包含return 語句時,將會出現一種意想不到的結果。

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

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

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

    JAVA SE7 關閉資源的處理

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

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

    try 塊退出時,會自動調用res.close()

    指定多個資源:

    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()); } 復制代碼

    不管這個塊如何退出,in 和 out 都會關閉。

    常規方式手動編程,就需要兩個嵌套的try/finally 語句。

    堆棧軌跡(stack trace)

    堆棧軌跡是一個方法調用過程的列表,它包含了程序執行過程中方法調用的特定位置。

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

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

    StackTraceElement 類含有能夠獲得文件名和當前執行的代碼行號的方法。同時,還含有能夠獲得類名和方法名的方法。

    靜態的 Thread.getAllStackTrace 方法,它可以產生所有線程的堆棧軌跡。例

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

    打印一個遞歸階乘的函數的堆棧情況

    public class StackTraceTest {/*** 計算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);} } 復制代碼

    計算factorial(3),打印一下內容

    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 復制代碼

    使用異常小技巧

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

    與執行簡單的測試相比,捕獲異常所花費的時間大大超過前者。因此使用異常的基本規則是,旨在異常情況下使用異常機制。

    不要過分地細化異常

    將整個任務包裝在一個try塊中,這樣,當任何一個操作出現問題時,整個任務都可以取消。

    利用異常層次結構

    • 不要只拋出 RuntimeException 異常。應該尋找更加適當的子類或創建自己的異常類。
    • 不要只捕獲Throwable 異常,否則,會使程序代碼更難讀、更難維護
    • 考慮受查異常和非受查異常的區別。
    • 將一種異常轉換成另一種更加適合的異常時不要猶豫。

    不要壓制異常

    在java中,往往強化地傾向關閉異常。

    在檢測錯誤時,“苛刻”要比放任更好

    例如,當棧空時,Stack.pop 是要返回一個null,還是拋出一個異常?我們認為:在出錯的地方拋出一個 EmptyStackException異常要比在后面拋出一個 NullPointerException 異常更好。

    不要羞于傳遞異常

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

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

    參考

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

    總結

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

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。