1.捕捉異常
Java中的異常捕獲結構由try
、catch
和finally
三個部分組成。其中try
語句用於存放可能發生異常的語句,catch
語句用於激發被捕獲的異常,finally
語句是異常結構最後處理的部分,不管有無異常發生,都會被執行,通常用於關閉資源。
可是在Java7中可使用try-catch-resources
用來自動嘗試關閉資源。
另外,finally語句塊在下面四種特殊狀況下不會被執行:html
System.exit()
退出程序。2.Java常見異常java
異常類 | 說明 |
---|---|
ClassCastExctption | 類型轉換異常 |
ClassNotFoundExctption | 未找到相應類異常 |
ArithmeticExctption | 算數異常 |
ArrayIndexOutOfBoundsExctption | 數組下標越界異常 |
ArrayStoreExctption | 數組中包含不兼容的值拋出的異常 |
SQLExctption | 操做數據庫異常 |
NullPointerExctption | 空指針異常 |
NoSuchFieldExctption | 字段未找到異常 |
NoSuchMethodExctption | 方法未找到拋出的異常 |
NumberFormatExctption | 字符串轉換爲數字拋出的異常 |
NegativeArraySizeExctption | 數組元素個數爲負數拋出的異常 |
StringIndexOutOfBoundsExctption | 字符串索引超出範圍拋出的異常 |
IOExctption | 輸入輸出異常 |
IllegalAccessExctption | 不容許訪問某類異常 |
InstantiationExctption | 當應用程序試圖使用Class類中的newInstance()方法建立一個類的實例,而指定的類對象沒法被實例化時,拋出該異常 |
EOFExctption | 文件已結束異常 |
FileNotFoundExctption | 文件未找到異常 |
順便分享一個偶然看到的頗有趣的對各類異常的解釋連接
3.自定義異常
使用Java異常類能夠描述在編程時出現的大部分異常的狀況,咱們只須要繼承異常類就能夠進行自定義異常的操做。
自定義異常的步驟:數據庫
try-catch
語句塊捕獲並處理,不然在方法的聲明處經過throws
關鍵字指明要拋出給方法調用者的異常4.Java異常類的結構編程
Thorwable類(表示可拋出)是全部異常和錯誤的超類,兩個直接子類爲Error和Exception,分別表示錯誤和異常。其中異常類Exception又分爲運行時異常(RuntimeException)和非運行時異常, 這兩種異常有很大的區別,也稱之爲不檢查異常(Unchecked Exception)和檢查異常(Checked Exception)。
數組
本次PTA做業題集異常
安全
結合題集題目7-1回答函數
答:以前編寫的代碼常常出現NullPointerException
(空指針異常)和ArrayIndexOutOfBoundsException
(數組下標越界異常)。
經過查詢JDK文檔:
工具
能夠看出這兩個異常都繼承自RuntimeException
(運行時異常),都屬於Unchecked Exception
,所以無需進行捕獲,系統會對其進行檢測。
對於空指針異常,能夠在使用對象時判斷對象是否爲空,而下標越界異常則是要判斷下標是否在數組長度的範圍內,總之Unchecked Exception
這類的異常就是要經過咱們本身檢查代碼行進行代碼的修改來避免異常。性能
答:在Throwable
下面有三個類:Error
、Exception
、RuntimeExcepyion
,其中Error
、RuntimeExcepyion
及其子類的的異常都屬於Unchecked Exception
,不用進行捕獲處理,而Exception
類中的其餘異常都屬於checked Exception
,須要使用try-catch
進行捕獲或是使用throw
關鍵字進行拋出。學習
題集題目7-2
這題只要在進行字符串轉換爲數字時進行'try-catch'的處理,若是出現異常除了要輸出外還要記得將下標減1。
對程序進行異常處理能夠有效的提升程序的健壯性,就像在這一題中,若是不進行相應的異常處理,那當程序中出現非整形數據時就會出錯,程序就會中止運行,可是當咱們加上異常處理後,程序就能夠正常運行並告知咱們錯誤信息。可是也要記住,不是全部的地方都要進行異常處理,咱們要忽略掉一些能夠忽略的異常,由於過多的異常處理在程序運行的時候還有可能會影響到程序的性能。
題集題目7-3
閱讀Integer.parsetInt
源代碼
Integer.parsetInt
一開始就有大量的拋出異常的代碼,這種作法有什麼好處?答:源代碼太長,就不貼出來了,經過源代碼能夠看出, Integer.parsetInt
雖然只有一種異常,即NumberFormatException
,可是在一開始,它就考慮了多種可以產生該異常的狀況進行異常的拋出,這樣能夠在傳入的數據的時候就進行判斷,看是否符合條件,這樣能夠避免傳入錯誤的參數而致使程序崩潰的狀況,讓程序更加健壯。
答:本題的代碼中,產生的異常只有IllegalArgumentException
可是根據不一樣的輸入數據,其產生該異常的緣由也不一樣,所以在本身編寫方法時就要告訴調用者產生異常的具體緣由,像begin>end或是begin和end範圍錯誤的關係。一樣的,在Integer.parsetInt
中也是如此,它也是隻有NumberFormatException
一種異常,可是多是由空值等緣由產生的。所以在編寫代碼時咱們要告訴調用者的不只僅是產生了什麼異常,還要準確的告訴調用者產生異常的具體緣由。
題集題目6-3
答:當程序運行時出錯時,這時的程序已是產生了讓程序沒法本身執行下去的錯誤,只能靠系統干預來強行終止程序,也就是程序崩潰的狀況。可是若是咱們使用拋出異常的方法來代替程序的運行時出錯,雖然兩者都能告訴咱們錯誤信息,可是後者中程序不會崩潰,就算是程序不去處理異常而致使程序的退出,也只是依靠程序的自身流程,屬於正常狀況。並且,咱們還能夠經過對異常進行處理來使程序可以繼續執行下去。就像本題中,咱們能夠經過異常處理來使得程序接收到非法參數時不會當即崩潰,並且能夠正常的執行下去,使這個程序變得更加健壯。
對於異常和返回錯誤自己的區別,那就是>異常是強類型的,類型安全的分支處理技術;而返回錯誤是其弱化的,不安全的版本。
相比於單純返回錯誤值,使用異常機制來處理有以下幾個優勢
throws
關鍵字,若是使用throws
關鍵字聲明該方法拋出的異常,能給咱們帶來什麼好處嗎?答:RuntimeException
類型的異常屬於Unchecked Exception
,在程序運行中系統會自動進行檢測,例如前面提到的空指針異常以及數組下標越界異常等,不須要使用throws
關鍵字來聲明。
若是用throw
關鍵字來聲明RuntimeException
類型的異常,雖然系統能夠編譯經過,可是隻能說這種方法有點多此一舉了。對於通常的運行時異常,咱們通常都是對其進行排錯處理,將錯誤代碼改正過來,而不是去報告錯誤信息。再者,若是全部的運行時異常都要用try-catch
來處理,那咱們的程序的性能反而會降低,所以最好不要用throw
關鍵字來聲明RuntimeException
類型的異常。
題集題目6-1
答:對於存在繼承關係的異常,要注意要讓子類的異常在父類異常的前面,不然子類的異常就不會被捕獲到,這是無心義的,固然,編譯器也不容許咱們這麼寫。
答:Java8中的多重異常捕獲可使咱們在一個catch語句中捕獲多個異常,以下:
try{ //一段代碼 } catch(IOException | SQLException | Exception ex){ throw new MyException(ex.getMessage()); }
能夠看出,不一樣的異常之間使用」|」來分隔,固然,這種多重異常捕獲的方法也一樣要注意異常之間的繼承關係,子類的異常必定要在父類異常的左邊,不然編譯器也會報錯。
byte[] content = null; FileInputStream fis = new FileInputStream("testfis.txt"); int bytesAvailabe = fis.available();//得到該文件可用的字節數 if(bytesAvailabe>0){ content = new byte[bytesAvailabe];//建立可容納文件大小的數組 fis.read(content);//將文件內容讀入數組 } System.out.println(Arrays.toString(content));//打印數組內容
答:改正後的代碼以下:
public class Test2 { public static void main(String[] args) throws IOException { Scanner sc = new Scanner(System.in); String file; int flag=1; byte[] content = null; FileInputStream fis = null; while(flag==1){ try { file = sc.next(); fis = new FileInputStream(file); flag=0; int bytesAvailabe = fis.available();// 得到該文件可用的字節數 if (bytesAvailabe > 0) { content = new byte[bytesAvailabe];// 建立可容納文件大小的數組 fis.read(content);// 將文件內容讀入數組 } System.out.println(Arrays.toString(content));// 打印數組內容 }catch(FileNotFoundException e){ System.out.println("找不到文件,請從新輸入文件名"); file = sc.next(); } catch (IOException e) { System.out.println("打開或讀取文件失敗"); } finally{ try { fis.close(); System.out.println("關閉文件ing"); } catch (Exception e) { System.out.println("關閉文件失敗"); } } } } }
答:不管是否拋出異常,finally
語句塊老是會被執行,所以finally
語句塊通常用來釋放資源,進行在使用finally關閉資源的時候,要注意close
也可能會產生空指針異常,所以也要對其進行try-catch
處理。
使用try-with-resources
改寫代碼:
public static void main(String[] args) throws IOException { byte[] content = null; try (FileInputStream fis = new FileInputStream("testfis.txt");){ int bytesAvailabe = fis.available();// 得到該文件可用的字節數 if (bytesAvailabe > 0) { content = new byte[bytesAvailabe];// 建立可容納文件大小的數組 fis.read(content);// 將文件內容讀入數組 } System.out.println(Arrays.toString(content));// 打印數組內容 } catch(FileNotFoundException e){ System.out.println("找不到文件,請從新輸入文件名"); } catch (IOException e) { System.out.println("打開或讀取文件失敗"); } } } }
使用這種方法來改寫代碼只要將須要關閉的資源放進try語句的圓括號裏便可,它能夠在最後自動幫咱們關閉咱們所打開的資源,咱們就不須要再去另寫一個finally來關閉這個資源。
登陸lib.jmu.edu.cn,對圖書進行搜索。而後登陸圖書館信息系統,查看個人圖書館。若是讓你實現一個圖書借閱系統,嘗試使用面向對象建模。
答:使用者有借書的用戶(程序中以學生來代替)和管理員。
用戶:
管理員:
答:存儲圖書信息使用Map鍵值對,key值存放圖書,value值存放數量。
借閱信息也使用Map鍵值對存儲
讀者信息使用Set集合存儲
截圖了部分掃描中出現的問題,發現本身在代碼規範中主要仍是起名的問題,以前也比較不會注意這方面,類名包名方法名之類的不會去在乎大小寫的問題。而後對於if還有for語句沒有大括號的緣由主要仍是由於平時寫的代碼的行數都很少,所以用不用大括號感受都不會有什麼影響,可能在比較大的程序裏會有必定的影響吧。
答:對類或者方法、成員變量起名的時候仍是要注意名字的合法性和準確性。不能像之前同樣爲了方便隨便用一個字母變量來代替
題目集:異常
須要有兩張圖(1. 排名圖。2.PTA提交列表圖)
須要將每週的代碼統計狀況融合到一張表中。
周次 | 總代碼量 | 新增代碼量 | 總文件數 | 新增文件數 |
---|---|---|---|---|
2 | 607 | 607 | 15 | 15 |
3 | 1642 | 1035 | 33 | 18 |
5 | 2044 | 402 | 42 | 9 |
6 | 2874 | 830 | 57 | 15 |
7 | 3161 | 287 | 63 | 6 |
8 | 4299 | 1138 | 72 | 9 |
9 | 4831 | 532 | 81 | 9 |
10 | 5475 | 644 | 93 | 12 |
11 | 5958 | 483 | 102 | 9 |