作業09-異常
1. 書面作業
本次PTA作業題集異常
1. 常用異常
結合題集題目7-1回答
1.1 自己以前編寫的代碼中經常出現什麽異常、需要捕獲嗎(為什麽)?應如何避免?
- ArrayIndexOutOfBoundsException(數組下標越界)無需捕獲,因為屬於RuntimeException。
- NullPointerException(空指針),無需捕獲,因為屬於RuntimeException。在應用時要註意判斷是否為空指針
- ClassCastException(類型轉換錯誤)不需要捕獲,在強制類型轉換時要先進行判斷
- IllegaArgumentException(輸入參數錯誤)不需要捕獲,註意輸入
1.2 什麽樣的異常要求用戶一定要使用捕獲處理?
除了Error與RuntimeException及其子類,其他異常都需要捕獲處理
2. 處理異常使你的程序更加健壯
題集題目7-2
2.1 實驗總結。並回答:怎麽樣才能讓你的程序更加健壯?
總結:輸入非整型的數時不放入數組,則設定一個flag,當輸入數為整型時存入,否則continue;
在可能報錯的時候加上 try-catch語句。
3. throw與throws
題集題目7-3
閱讀Integer.parsetInt
源代碼
3.1 Integer.parsetInt
一開始就有大量的拋出異常的代碼,這種做法有什麽好處?
3.2 結合自己編寫的程序與3.1,分析自己編寫的方法拋出異常時一般需要傳遞給調用者一些什麽信息?
題目7-3中拋出異常 IllegalArgumentException
時會傳遞給調用者知道,具體是哪個步驟(或輸入)錯誤,這樣下次調用時可以避免錯誤
4. 用異常改進ArrayIntegerStack
題集題目6-3
4.1 結合6-3代碼,回答使用拋出異常的方式代表程序運行時出錯有什麽好處?比單純的返回錯誤值,有何優點?
單純返回錯誤值,讓調用者很難直接找到錯誤點,使用拋出異常的方式更加直觀,便於調用者修改,程序也不會終止
4.2 如果一個方法內部的內碼拋出的是RuntimeException類型的異常,那麽方法聲明是否應該使用throws
關鍵字,如果使用throws
關鍵字聲明該方法拋出的異常,能給我們帶來什麽好處嗎?
可以不使用,因為不是checked Exception。
這樣就可以在調用該方法的地方使用try-catch捕獲其拋出的異常
5. 函數題-多種異常的捕獲
題集題目6-1
5.1 結合6-1代碼,回答:一個try塊中如果可能拋出多種異常,且異常之間可能有繼承關系,捕獲時需要註意些什麽?
catch的異常一定是子類在前,父類在最後
5.2 一個try塊中如果可能拋出多種異常,使用Java8的多重異常捕獲語法需要註意些什麽?
6. 為如下代碼加上異常處理
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));//打印數組內容
6.1 改正代碼,並增加如下功能。當找不到文件時,需提示用戶找不到文件xxx,請重新輸入文件名
,然後嘗試重新打開。 如果是其他異常則提示打開或讀取文件失敗!
。
註1:裏面有多個方法均可能拋出異常。
功能2:需要添加finally
關閉文件。無論上面的代碼是否產生異常,總要提示關閉文件ing
。如果關閉文件失敗,提示關閉文件失敗!
public static void main(String[] args){ // TODO Auto-generated method stub byte[] content = null; FileInputStream fis = null; String file=null; Scanner sc=new Scanner(System.in); try{ file=sc.next(); fis = new FileInputStream(file); int bytesAvailabe = fis.available();//獲得該文件可用的字節數 if(bytesAvailabe>0){ content = new byte[bytesAvailabe];//創建可容納文件大小的數組 fis.read(content);//將文件內容讀入數組 } }catch (FileNotFoundException e) { System.out.println("找不到文件,請重新輸入文件名"); file=sc.next(); }catch(IOException e){ System.out.println("打開或讀取文件失敗!"); }finally{ System.out.println("關閉文件ing"); try { //關閉資源也有可能出錯 fis.close(); } catch (Exception e) { System.out.println("關閉文件失敗!"); } } System.out.println(Arrays.toString(content));//打印數組內容 }
6.2 結合題集6-2
代碼,要將什麽樣操作放在finally塊?為什麽?使用finally關閉資源需要註意一些什麽?
finally中是一定會被執行的,eg:將文件關閉,就可以寫在finally中,要註意關閉是否關閉成功,是否也需要try-catch
6.3 使用Java7中的try-with-resources
來改寫上述代碼實現自動關閉資源。簡述這種方法有何好處?
自動關閉,不用判斷關閉過程中是否會產生異常
public static void main(String[] args){ Scanner sc=new Scanner(System.in); String str; byte[] content = null; //FileInputStream fis=null; try (FileInputStream fis = new FileInputStream("E://test/testfis.txt")){ //fis = new FileInputStream("testfis.txt"); int bytesAvailabe = fis.available();//獲得該文件可用的字節數 if(bytesAvailabe>0){ content = new byte[bytesAvailabe];//創建可容納文件大小的數組 fis.read(content);//將文件內容讀入數組 } }catch(FileNotFoundException e){ System.out.println("找不到文件"); }catch(IOException e) { System.out.println("打開或讀取文件失敗"); } System.out.println(Arrays.toString(content));//打印數組內容 }
7. 讀取文件並組裝對象
實驗任務書中中的題目3:讀取文件並組裝對象
7.1 給出關鍵代碼(需出現你的學號)。額外要求:捕獲異常時,將錯誤的信息按照出錯原因:行號:該行內容格式輸出。
/*201721123095*/ public static void main(String[] args){ Scanner in =null; ArrayList<User>student=new ArrayList<User>(); try { in= new Scanner(new File("E://test/身份證號.txt"));//為myfile.txt這個File創建一個掃描器in int count=0; while(in.hasNextLine()){ String line = in.nextLine();//讀出myfile.txt的下一行 count++; Scanner lineScanner = new Scanner(line);//為每一行建立一個掃描器 //System.out.println("lineScanner="+lineScanner); lineScanner.useDelimiter(" ");//使用空格作為分隔符 //System.out.println(line); try { String a1 = lineScanner.next();//姓名 if(a1.length()==0||a1.length()>10) { throw new IllegalArgumentException("a1.length = " + a1.length()); } String a2 = lineScanner.next();//身份證號 if(a2.length()==0) { throw new IllegalArgumentException("a2.length = " + a2.length()); } String a3 = lineScanner.next();//性別 if(!a3.equals("男")&&!a3.equals("女")) { throw new IllegalArgumentException("性別出錯:" + a3); } String a4 = lineScanner.next();//年齡 String a5 = lineScanner.next();//地址 while(lineScanner.hasNext()){//謹防地址只有一段 a5 += lineScanner.next(); } User user=new User(a1,a2,a3,Integer.parseInt(a4),a5); student.add(user); }catch(IllegalArgumentException e) { System.out.println("出錯類型:"+e+"出錯在"+count+"行:"+line); } //System.out.println(a1+a2+a3+a4+a5); } }catch(FileNotFoundException e) { e.printStackTrace(); }finally { if(in!=null) in.close(); } Collections.sort(student,new AgeComparator()); for (User e : student) { System.out.println(e.toString()); } }
運行結果:
7.2 如果文件有上萬行文本,出錯的信息可能有很多行,如果將出錯信息直接輸出到控制臺容易被忽略,請問如何解決?
可以改成拋出異常,讓調用者清晰知道是哪裏出錯
作業09-異常