實驗九異常、斷言與日誌java
實驗時間 2018-10-25程序員
第一部分:理論部分編程
1.異常:在程序的執行過程當中所發生的異常事件,它中斷指令的正常執行。數組
Java的異常處理機制能夠控制程序從錯誤產生的位置轉移到可以進行錯誤處理的位置。 安全
程序中出現的常見的錯誤和問題有:用戶輸入錯誤;設備錯誤;物理限制;代碼錯誤。網絡
Java把程序運行時可能遇到的錯誤分爲兩類:非致命異常:經過某種修正後程序還能繼續執行。這類錯誤叫做異常。如:文件不存在、無效的數組下標、空引用、網絡斷開、打印機脫機、磁盤滿等。 Java中提供了一種獨特的處理異常的機制,經過異常來處理程序設計中出現的錯誤。致命異常:程序遇到了很是嚴重的不正常狀態,不能簡單恢復執行,是致命性錯誤。如:內存耗盡、系統內部錯誤等。這種錯誤程序自己沒法解決。app
2.Java中的異常類可分爲兩大類: Error :Error類層次結構描述了Java 運行時系統的內部錯誤和資源耗盡錯誤。應用程序不該該捕獲這類異常,也不會拋出這種異常 。 Exception類: Exception層次結構又分解爲兩個分支:一個分支派生於 RuntimeException;另外一個分支包含其餘異常。3.RuntimeException爲運行時異常類,通常是程序錯誤產生。派生於RuntimeException的異常包含下面幾種狀況:錯誤的類型轉換;數組訪問越界;訪問空指針。less
4.將派生於Error類或RuntimeException類的全部異常稱爲未檢查異常,編譯器容許不對它們作出異常處理。 注意:「若是出現RuntimeException異常,就必定是程序員的問題!!!」dom
5.非運行時異常,程序自己沒有問題,但因爲某種狀況的變化,程序不能正常運行,致使異常出現。除了運行時異常以外的其它繼承自Exception類的異常類包括:試圖在文件尾部後面讀取數據;試圖打開一個錯誤格式的URL。 編譯器要求程序必須對這類異常進行處理 (checked),稱爲已檢查異常eclipse
6. RuntimeException運行時異常類:ArithmeticException: 算術異常類;ArrayStoreException: 數組存儲異常類;ClassCastException: 類型強制轉換異常類;IndexOutOfBoundsException: 下標越界異常類;NullPointerException: 空指針異常類;SecurityException: 違背安全原則異常類。
7.IOException:輸入輸出異常類:IOException:申請I/O操做沒有正常完成。EOFException:在輸入操做正常結束前碰見了文件結束符。FileNotFountException:在文件系統中,沒有找到由文件名字符串指定的文件。
8.聲明拋出異常:若是一個方法可能會生成一些異常,可是該方法並不確切知道如何對這些異常事件進行處理,此時,這個方法就需聲明拋出這些異常。「一個方法不只須要告訴編譯器將要返回什麼值,還要告訴編譯器可能發生什麼異常。」
9.聲明拋出異常在方法聲明中用throws子句中來指明。例如:public FileInputStream(String name ) throws FileNotFoundException
10。如下4種狀況須要方法用throws子句聲明拋出異常:一、方法調用了一個拋出已檢查異常的方法。程序運行過程當中可能會發生錯誤,而且利用throw語句拋出一個已檢查異常對象。 三、程序出現錯誤。例如,a[-1] = 0/四、Java虛擬機和運行時庫出現的內部異常。
11.一個方法必須聲明該方法全部可能拋出的已檢查異常,而未檢查異常要麼不可控制(Error),要麼應該避免發生(RuntimeException)。若是方法沒有聲明全部可能發生的已檢查異常,編譯器會給出一個錯誤消息。當Java應用程序出現錯誤時,會根據錯誤類型產生一個異常對象,這個對象包含了異常的類型和錯誤出現時程序所處的狀態信息。把異常對象遞交給Java編譯器的過程稱爲拋出。拋出異常要生成異常對象,異常對象可由某些類的實例生成,也能夠由JVM生成。拋出異常對象經過throw語句來實現。
12.如何拋出異常:首先決定拋出異常類型。例如:當從一個長爲 1024的文件中讀取數據時,但讀到733時遇到了文件結束標記,此時應拋出一個異常,EOFException比較合適。代碼爲:throw new EOFException(); 或者: EOFException e= new EOFException(); throw e;
13.對於已存在的異常類,拋出該類的異常對象很是容易,步驟是:找到一個合適的異常類;建立這個類的一個對象;將該對象拋出。一個方法拋出了異常後,它就不能返回調用者了。
14.建立異常類:自定義異常類:定義一個派生於Exception的直接或間接子類。如一個派生於IOException的類。自定義的異常類應該包括兩個構造器:默認構造器;帶有詳細描述信息的構造器(超類Throwable的toString方法會打印出這些詳細信息,有利於代碼調程序運行期間,異常發生時,Java運行系統從異常生成的代碼塊開始,尋找相應的異常處理代碼,並將異常交給該方法處理,這一過程叫做捕獲。某個異常發生時,若程序沒有在任何地方進行該異常的捕獲,則程序就會終止執行,並在控制檯上輸出異常信息。若要捕獲一個異常,須要在程序中設置一個try/catch/ finally塊: try語句括住可能拋出異常的代碼段。catch語句指明要捕獲的異常及相應的處理代碼。finally語句指明必須執行的程序
catch子句:catch塊是對異常對象進行處理的代碼;每一個try代碼塊能夠伴隨一個或多個catch語句,用於處理 try代碼塊中所生成的各種異常事件;catch語句只須要一個形式參數指明它所能捕獲的異常類對象,這個異常類必須是Throwable的子類,運行時系統經過參數值把被拋出的異常對象傳遞給catch塊;catch塊能夠經過異常對象調用類Throwable所提供的方法。getMessage()用來獲得有關異常事件的信息;printStackTrace()用來跟蹤異常事件發生時執行堆棧的內容。
1、實驗目的與要求
(1) 掌握java異常處理技術;
(2) 瞭解斷言的用法;
(3) 瞭解日誌的用途;
(4) 掌握程序基礎調試技巧;
2、實驗內容和步驟
實驗1:用命令行與IDE兩種環境下編輯調試運行源程序ExceptionDemo一、ExceptionDemo2,結合程序運行結果理解程序,掌握未檢查異常和已檢查異常的區別。
//異常示例1 public class ExceptionDemo1 { public static void main(String args[]) { int a = 0; System.out.println(5 / a); } } |
//異常示例2 import java.io.*;
public class ExceptionDemo2 { public static void main(String args[]) { FileInputStream fis=new FileInputStream("text.txt");//JVM自動生成異常對象 int b; while((b=fis.read())!=-1) { System.out.print(b); } fis.close(); } } |
1 //異常示例1 2 public class ExceptionDemo1 { 3 public static void main(String args[]) { 4 int a = 0; 5 System.out.println(5 / a); 6 } 7 }
作出異常判斷
1 package t; 2 public class ExceptionDemo1 { 3 public static void main(String args[]) { 4 int a = 0; 5 if(a==0){ 6 System.out.println("中斷!"); 7 } 8 else{ 9 System.out.println(5 / a); 10 } 11 } 12 }
1 //異常示例2 2 import java.io.*; 3 4 public class ExceptionDemo2 { 5 public static void main(String args[]) 6 { 7 FileInputStream fis=new FileInputStream("text.txt");//JVM自動生成異常對象 8 int b; 9 while((b=fis.read())!=-1) 10 { 11 System.out.print(b); 12 } 13 fis.close(); 14 } 15 }
作出處理
1 import java.io.*; 2 3 public class ExceptionDemo2 { 4 public static void main(String args[]) { 5 FileInputStream fis; 6 try { 7 fis = new FileInputStream("text.txt"); 8 // JVM自動生成異常對象 9 int b; 10 while ((b = fis.read()) != -1) { 11 System.out.print(b); 12 } 13 fis.close(); 14 } catch (Exception e) { 15 // TODO 自動生成的 catch 塊 16 e.printStackTrace(); 17 } 18 } 19 }
實驗2: 導入如下示例程序,測試程序並進行代碼註釋。
測試程序1:
l 在elipse IDE中編輯、編譯、調試運行教材281頁7-1,結合程序運行結果理解程序;
l 在程序中相關代碼處添加新知識的註釋;
l 掌握Throwable類的堆棧跟蹤方法;
1 package stackTrace; 2 3 import java.util.*; 4 5 /** 6 * A program that displays a trace feature of a recursive method call. 7 * @version 1.01 2004-05-10 8 * @author Cay Horstmann 9 */ 10 public class StackTraceTest 11 { 12 /** 13 * Computes the factorial of a number 14 * @param n a non-negative integer 15 * @return n! = 1 * 2 * . . . * n 16 */ 17 public static int factorial(int n) 18 { 19 System.out.println("factorial(" + n + "):"); 20 Throwable t = new Throwable();//生成Throwable類對象 21 StackTraceElement[] frames = t.getStackTrace(); 22 //使用getStackTrace方法獲得 StackTraceElement對象的一個數組 23 for (StackTraceElement f : frames) 24 System.out.println(f); 25 int r; 26 if (n <= 1) r = 1; 27 else r = n * factorial(n - 1); 28 System.out.println("return " + r); 29 return r; 30 } 31 32 public static void main(String[] args) 33 { 34 Scanner in = new Scanner(System.in); 35 System.out.print("Enter n: "); 36 int n = in.nextInt();//讀取下一行的內容 37 factorial(n); 38 } 39 }
測試程序2:
l Java語言的異常處理有積極處理方法和消極處理兩種方式;
l 下列兩個簡答程序範例給出了兩種異常處理的代碼格式。在elipse IDE中編輯、調試運行源程序ExceptionalTest.java,將程序中的text文件更換爲身份證號.txt,要求將文件內容讀入內容,並在控制檯顯示;
l 掌握兩種異常處理技術的特色。
//積極處理方式 import java.io.*;
class ExceptionTest { public static void main (string args[]) { try{ FileInputStream fis=new FileInputStream("text.txt"); } catch(FileNotFoundExcption e) { …… } …… } } |
//消極處理方式
import java.io.*; class ExceptionTest { public static void main (string args[]) throws FileNotFoundExcption { FileInputStream fis=new FileInputStream("text.txt"); } } |
1 //積極處理 2 import java.io.*; 3 class ExceptionDemo1 { 4 public static void main (String args[]) 5 { 6 File fis=new File("身份證號.txt"); 7 try{ 8 9 10 FileReader fr = new FileReader(fis); 11 BufferedReader br = new BufferedReader(fr); 12 try { 13 String s, s2 = new String(); 14 while ((s = br.readLine()) != null) { 15 s2 += s + "\n "; 16 } 17 br.close(); 18 System.out.println(s2); 19 } catch (IOException e) { 20 // TODO Auto-generated catch block 21 e.printStackTrace(); 22 } 23 } catch (FileNotFoundException e) { 24 // TODO Auto-generated catch block 25 e.printStackTrace(); 26 } 27 28 } 29 }
1 //消極處理方式 2 3 import java.io.*; 4 class ExceptionDemo1 { 5 public static void main (String args[]) throws IOException 6 { 7 File fis=new File("身份證號.txt"); 8 FileReader fr = new FileReader(fis); 9 BufferedReader br = new BufferedReader(fr); 10 String s, s2 = new String(); 11 12 while ((s = br.readLine()) != null) { 13 s2 += s + "\n "; 14 } 15 br.close(); 16 System.out.println(s2); 17 } 18 }
實驗3: 編程練習
練習1:
l 編制一個程序,將身份證號.txt 中的信息讀入到內存中;
l 按姓名字典序輸出人員信息;
l 查詢最大年齡的人員信息;
l 查詢最小年齡人員信息;
l 輸入你的年齡,查詢身份證號.txt中年齡與你最近人的姓名、身份證號、年齡、性別和出生地;
l 查詢人員中是否有你的同鄉;
l 在以上程序適當位置加入異常捕獲代碼。
1 import java.io.BufferedReader; 2 import java.io.File; 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.IOException; 6 import java.io.InputStreamReader; 7 import java.util.ArrayList; 8 import java.util.Arrays; 9 import java.util.Collections; 10 import java.util.Scanner; 11 12 13 public class Test{ 14 15 private static ArrayList<Person> Personlist1; 16 public static void main(String[] args) { 17 18 Personlist1 = new ArrayList<>(); 19 20 Scanner scanner = new Scanner(System.in); 21 File file = new File("C:\\Users\\lenovo\\Documents\\身份證"); 22 23 try { 24 FileInputStream F = new FileInputStream(file); 25 BufferedReader in = new BufferedReader(new InputStreamReader(F)); 26 String temp = null; 27 while ((temp = in.readLine()) != null) { 28 29 Scanner linescanner = new Scanner(temp); 30 31 linescanner.useDelimiter(" "); 32 String name = linescanner.next(); 33 String id = linescanner.next(); 34 String sex = linescanner.next(); 35 String age = linescanner.next(); 36 String place =linescanner.nextLine(); 37 Person Person = new Person(); 38 Person.setname(name); 39 Person.setid(id); 40 Person.setsex(sex); 41 int a = Integer.parseInt(age); 42 Person.setage(a); 43 Person.setbirthplace(place); 44 Personlist1.add(Person); 45 46 } 47 } catch (FileNotFoundException e) { 48 System.out.println("查找不到信息"); 49 e.printStackTrace(); 50 } catch (IOException e) { 51 System.out.println("信息讀取有誤"); 52 e.printStackTrace(); 53 } 54 boolean isTrue = true; 55 while (isTrue) { 56 System.out.println("1:按姓名字典序輸出人員信息;"); 57 System.out.println("2:查詢最大年齡與最小年齡人員信息;"); 58 System.out.println("3.輸入你的年齡,查詢身份證號.txt中年齡與你最近人的姓名、身份證號、年齡、性別和出生地"); 59 System.out.println("4:按省份找你的同鄉;"); 60 System.out.println("5:退出"); 61 int type = scanner.nextInt(); 62 switch (type) { 63 case 1: 64 Collections.sort(Personlist1); 65 System.out.println(Personlist1.toString()); 66 break; 67 case 2: 68 69 int max=0,min=100;int j,k1 = 0,k2=0; 70 for(int i=1;i<Personlist1.size();i++) 71 { 72 j=Personlist1.get(i).getage(); 73 if(j>max) 74 { 75 max=j; 76 k1=i; 77 } 78 if(j<min) 79 { 80 min=j; 81 k2=i; 82 } 83 84 } 85 System.out.println("年齡最大:"+Personlist1.get(k1)); 86 System.out.println("年齡最小:"+Personlist1.get(k2)); 87 break; 88 case 3: 89 System.out.println("place?"); 90 String find = scanner.next(); 91 String place=find.substring(0,3); 92 String place2=find.substring(0,3); 93 for (int i = 0; i <Personlist1.size(); i++) 94 { 95 if(Personlist1.get(i).getbirthplace().substring(1,4).equals(place)) 96 { 97 System.out.println("你的同鄉:"+Personlist1.get(i)); 98 } 99 } 100 101 break; 102 case 4: 103 System.out.println("年齡:"); 104 int yourage = scanner.nextInt(); 105 int close=ageclose(yourage); 106 int d_value=yourage-Personlist1.get(close).getage(); 107 System.out.println(""+Personlist1.get(close)); 108 109 break; 110 case 5: 111 isTrue = false; 112 System.out.println("再見!"); 113 break; 114 default: 115 System.out.println("輸入有誤"); 116 } 117 } 118 } 119 public static int ageclose(int age) { 120 int m=0; 121 int max=53; 122 int d_value=0; 123 int k=0; 124 for (int i = 0; i < Personlist1.size(); i++) 125 { 126 d_value=Personlist1.get(i).getage()-age; 127 if(d_value<0) d_value=-d_value; 128 if (d_value<max) 129 { 130 max=d_value; 131 k=i; 132 } 133 134 } return k; 135 136 } 137 } 138
1 public class Person implements Comparable<Person> { 2 private String name; 3 private String id; 4 private int age; 5 private String sex; 6 private String birthplace; 7 8 public String getname() { 9 return name; 10 } 11 public void setname(String name) { 12 this.name = name; 13 } 14 public String getid() { 15 return id; 16 } 17 public void setid(String id) { 18 this.id= id; 19 } 20 public int getage() { 21 22 return age; 23 } 24 public void setage(int age) { 25 // int a = Integer.parseInt(age); 26 this.age= age; 27 } 28 public String getsex() { 29 return sex; 30 } 31 public void setsex(String sex) { 32 this.sex= sex; 33 } 34 public String getbirthplace() { 35 return birthplace; 36 } 37 public void setbirthplace(String birthplace) { 38 this.birthplace= birthplace; 39 } 40 41 public int compareTo(Person o) { 42 return this.name.compareTo(o.getname()); 43 44 } 45 46 public String toString() { 47 return name+"\t"+sex+"\t"+age+"\t"+id+"\t"; 48 49 }
注:如下實驗課後完成
練習2:
l 編寫一個計算器類,能夠完成加、減、乘、除的操做;
l 利用計算機類,設計一個小學生100之內數的四則運算練習程序,由計算機隨機產生10道加減乘除練習題,學生輸
入答案,由程序檢查答案是否正確,每道題正確計10分,錯誤不計分,10道題測試結束後給出測試總分;
l 將程序中測試練習題及學生答題結果輸出到文件,文件名爲test.txt;
l 在以上程序適當位置加入異常捕獲代碼。
1 import java.util.Scanner; 2 import java.io.FileNotFoundException; 3 import java.io.PrintWriter; 4 import java.util.Random; 5 6 public class Demo { 7 public static void main(String[] args) { 8 9 Scanner in = new Scanner(System.in); 10 Number counter = new Number(); 11 PrintWriter out = null; 12 try { 13 out = new PrintWriter("text.txt"); 14 } catch (FileNotFoundException e) { 15 // TODO Auto-generated catch block 16 e.printStackTrace(); 17 } 18 int sum = 0; 19 20 for (int i = 1; i <= 10; i++) { 21 22 int a = (int) Math.round(Math.random() * 100); 23 int b = (int) Math.round(Math.random() * 100); 24 int m = (int) Math.round(Math.random() * 3); 25 Random n = new Random(); 26 27 switch (m) { 28 case 0: 29 System.out.println(i + ": " + a + "/" + b + "="); 30 31 while (b == 0) { 32 b = (int) Math.round(Math.random() * 100); 33 } 34 35 int c = in.nextInt(); 36 out.println(a + "/" + b + "=" + c); 37 if (c == counter.division(a, b)) { 38 sum += 10; 39 System.out.println("恭喜答案正確"); 40 } else { 41 System.out.println("抱歉,答案錯誤"); 42 } 43 44 break; 45 46 case 1: 47 System.out.println(i + ": " + a + "*" + b + "="); 48 int c1 = in.nextInt(); 49 out.println(a + "*" + b + "=" + c1); 50 if (c1 == counter.multiplication(a, b)) { 51 sum += 10; 52 System.out.println("恭喜答案正確"); 53 } else { 54 System.out.println("抱歉,答案錯誤"); 55 } 56 break; 57 case 2: 58 System.out.println(i + ": " + a + "+" + b + "="); 59 int c2 = in.nextInt(); 60 out.println(a + "+" + b + "=" + c2); 61 if (c2 == counter.add(a, b)) { 62 sum += 10; 63 System.out.println("恭喜答案正確"); 64 } else { 65 System.out.println("抱歉,答案錯誤"); 66 } 67 68 break; 69 case 3: 70 System.out.println(i + ": " + a + "-" + b + "="); 71 int c3 = in.nextInt(); 72 out.println(a + "-" + b + "=" + c3); 73 if (c3 == counter.reduce(a, b)) { 74 sum += 10; 75 System.out.println("恭喜答案正確"); 76 } else { 77 System.out.println("抱歉,答案錯誤"); 78 } 79 break; 80 81 } 82 83 } 84 System.out.println("成績" + sum); 85 out.println("成績:" + sum); 86 out.close(); 87 88 } 89 } 90
1 public class Number { 2 private int a; 3 private int b; 4 5 public int add(int a, int b) { 6 return a + b; 7 } 8 9 public int reduce(int a, int b) { 10 return a - b; 11 } 12 13 public int multiplication(int a, int b) { 14 return a * b; 15 } 16 17 public int division(int a, int b) { 18 if (b != 0) 19 return a / b; 20 else 21 return 0; 22 } 23 24 }
實驗4:斷言、日誌、程序調試技巧驗證明驗。
實驗程序1:
l 在elipse下調試程序AssertDemo,結合程序運行結果理解程序;
l 註釋語句test1(-5);後從新運行程序,結合程序運行結果理解程序;
l 掌握斷言的使用特色及用法。
//斷言程序示例 public class AssertDemo { public static void main(String[] args) { test1(-5); test2(-3); }
private static void test1(int a){ assert a > 0; System.out.println(a); } private static void test2(int a){ assert a > 0 : "something goes wrong here, a cannot be less than 0"; System.out.println(a); } } |
1 public class AssertDemo { 2 public static void main(String[] args) { 3 test1(-5); 4 test2(-3); 5 } 6 7 private static void test1(int a){ 8 assert a > 0;//assert宏的原型定義在<assert.h>中,做用是若是它的條件返回錯誤,則終止程序執行 9 System.out.println(a); 10 } 11 private static void test2(int a){ 12 assert a > 0 : "這裏出錯了,a不能小於0"; 13 System.out.println(a); 14 } 15 }
註釋前結果
1 public class AssertDemo { 2 public static void main(String[] args) { 3 // test1(-5); 4 test2(-3); 5 } 6 7 private static void test1(int a){ 8 assert a > 0;//assert宏的原型定義在<assert.h>中,做用是若是它的條件返回錯誤,則終止程序執行 9 System.out.println(a); 10 } 11 private static void test2(int a){ 12 assert a > 0 : "這裏出錯了,a不能小於0"; 13 System.out.println(a); 14 } 15 }
註釋後結果
實驗程序2:
l 用JDK命令調試運行教材298頁-300頁程序7-2,結合程序運行結果理解程序;
l 並掌握Java日誌系統的用途及用法。
1 import java.awt.*; 2 import java.awt.event.*; 3 import java.io.*; 4 import java.util.logging.*; 5 import javax.swing.*; 6 7 /** 8 * A modification of the image viewer program that logs various events. 9 * @version 1.03 2015-08-20 10 * @author Cay Horstmann 11 */ 12 public class LoggingImageViewer 13 { 14 public static void main(String[] args) 15 { 16 //將全部消息記錄到應用程序特定的文件中 17 if (System.getProperty("java.util.logging.config.class") == null 18 && System.getProperty("java.util.logging.config.file") == null) 19 { 20 try//放入可能出錯的語句 21 { 22 Logger.getLogger("com.horstmann.corejava").setLevel(Level.ALL);//獲得日誌記錄器 23 final int LOG_ROTATION_COUNT = 10; 24 Handler handler = new FileHandler("%h/LoggingImageViewer.log", 0, LOG_ROTATION_COUNT); 25 Logger.getLogger("com.horstmann.corejava").addHandler(handler); 26 } 27 catch (IOException e) 28 { 29 Logger.getLogger("com.horstmann.corejava").log(Level.SEVERE, 30 "Can't create log file handler", e); 31 } 32 } 33 34 EventQueue.invokeLater(() ->//使事件派發線程上的可運行對象排隊 35 { 36 Handler windowHandler = new WindowHandler(); 37 windowHandler.setLevel(Level.ALL); 38 Logger.getLogger("com.horstmann.corejava").addHandler(windowHandler); 39 40 JFrame frame = new ImageViewerFrame(); 41 frame.setTitle("LoggingImageViewer"); 42 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 43 44 Logger.getLogger("com.horstmann.corejava").fine("Showing frame"); 45 frame.setVisible(true); 46 }); 47 } 48 } 49 50 /** 51 * 顯示圖像的幀。 52 */ 53 class ImageViewerFrame extends JFrame 54 { 55 private static final int DEFAULT_WIDTH = 300; 56 private static final int DEFAULT_HEIGHT = 400; 57 58 private JLabel label; 59 private static Logger logger = Logger.getLogger("com.horstmann.corejava"); 60 61 public ImageViewerFrame() 62 { 63 logger.entering("ImageViewerFrame", "<init>"); 64 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 65 66 //設置菜單欄 67 JMenuBar menuBar = new JMenuBar(); 68 setJMenuBar(menuBar); 69 70 JMenu menu = new JMenu("File"); 71 menuBar.add(menu); 72 73 JMenuItem openItem = new JMenuItem("Open"); 74 menu.add(openItem); 75 openItem.addActionListener(new FileOpenListener()); 76 77 JMenuItem exitItem = new JMenuItem("Exit"); 78 menu.add(exitItem); 79 exitItem.addActionListener(new ActionListener() 80 { 81 public void actionPerformed(ActionEvent event) 82 { 83 logger.fine("Exiting."); 84 System.exit(0); 85 } 86 }); 87 88 //使用標籤顯示圖像 89 label = new JLabel(); 90 add(label); 91 logger.exiting("ImageViewerFrame", "<init>"); 92 } 93 94 private class FileOpenListener implements ActionListener 95 { 96 public void actionPerformed(ActionEvent event) 97 { 98 logger.entering("ImageViewerFrame.FileOpenListener", "actionPerformed", event); 99 100 //設置文件選擇器 101 JFileChooser chooser = new JFileChooser(); 102 chooser.setCurrentDirectory(new File(".")); 103 104 //接受以.gif結尾的全部文件 105 chooser.setFileFilter(new javax.swing.filechooser.FileFilter() 106 { 107 public boolean accept(File f) 108 { 109 return f.getName().toLowerCase().endsWith(".gif") || f.isDirectory(); 110 } 111 112 public String getDescription() 113 { 114 return "GIF Images"; 115 } 116 }); 117 118 //顯示文件選擇器對話框 119 int r = chooser.showOpenDialog(ImageViewerFrame.this); 120 121 // 若是圖像文件被接受,將其設置爲標籤的圖標 122 if (r == JFileChooser.APPROVE_OPTION) 123 { 124 String name = chooser.getSelectedFile().getPath(); 125 logger.log(Level.FINE, "Reading file {0}", name); 126 label.setIcon(new ImageIcon(name)); 127 } 128 else logger.fine("File open dialog canceled."); 129 logger.exiting("ImageViewerFrame.FileOpenListener", "actionPerformed"); 130 } 131 } 132 } 133 134 /** 135 * 用於在窗口中顯示日誌記錄的處理程序。 136 */ 137 class WindowHandler extends StreamHandler//繼承 138 { 139 private JFrame frame; 140 141 public WindowHandler() 142 { 143 frame = new JFrame(); 144 final JTextArea output = new JTextArea(); 145 output.setEditable(false); 146 frame.setSize(200, 200); 147 frame.add(new JScrollPane(output)); 148 frame.setFocusableWindowState(false); 149 frame.setVisible(true); 150 setOutputStream(new OutputStream() 151 { 152 public void write(int b) 153 { 154 } 155 156 public void write(byte[] b, int off, int len) 157 { 158 output.append(new String(b, off, len)); 159 } 160 }); 161 } 162 163 public void publish(LogRecord record) 164 { 165 if (!frame.isVisible()) return; 166 super.publish(record); 167 flush(); 168 } 169 }
實驗結果
實驗程序3:
l 用JDK命令調試運行教材298頁-300頁程序7-2,結合程序運行結果理解程序;,
l 按課件66-77內容練習並掌握Elipse的經常使用調試技術。
1 import java.awt.*; 2 import java.awt.event.*; 3 import java.io.*; 4 import java.util.logging.*; 5 import javax.swing.*; 6 7 /** 8 * A modification of the image viewer program that logs various events. 9 * @version 1.03 2015-08-20 10 * @author Cay Horstmann 11 */ 12 public class LoggingImageViewer 13 { 14 public static void main(String[] args) 15 { 16 //將全部消息記錄到應用程序特定的文件中 17 if (System.getProperty("java.util.logging.config.class") == null 18 && System.getProperty("java.util.logging.config.file") == null) 19 { 20 try//放入可能出錯的語句 21 { 22 Logger.getLogger("com.horstmann.corejava").setLevel(Level.ALL);//獲得日誌記錄器 23 final int LOG_ROTATION_COUNT = 10; 24 Handler handler = new FileHandler("%h/LoggingImageViewer.log", 0, LOG_ROTATION_COUNT); 25 Logger.getLogger("com.horstmann.corejava").addHandler(handler); 26 } 27 catch (IOException e) 28 { 29 Logger.getLogger("com.horstmann.corejava").log(Level.SEVERE, 30 "Can't create log file handler", e); 31 } 32 } 33 34 EventQueue.invokeLater(() ->//使事件派發線程上的可運行對象排隊 35 { 36 Handler windowHandler = new WindowHandler(); 37 windowHandler.setLevel(Level.ALL); 38 Logger.getLogger("com.horstmann.corejava").addHandler(windowHandler); 39 40 JFrame frame = new ImageViewerFrame(); 41 frame.setTitle("LoggingImageViewer"); 42 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 43 44 Logger.getLogger("com.horstmann.corejava").fine("Showing frame"); 45 frame.setVisible(true); 46 }); 47 } 48 } 49 50 /** 51 * 顯示圖像的幀。 52 */ 53 class ImageViewerFrame extends JFrame 54 { 55 private static final int DEFAULT_WIDTH = 300; 56 private static final int DEFAULT_HEIGHT = 400; 57 58 private JLabel label; 59 private static Logger logger = Logger.getLogger("com.horstmann.corejava"); 60 61 public ImageViewerFrame() 62 { 63 logger.entering("ImageViewerFrame", "<init>"); 64 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 65 66 //設置菜單欄 67 JMenuBar menuBar = new JMenuBar(); 68 setJMenuBar(menuBar); 69 70 JMenu menu = new JMenu("File"); 71 menuBar.add(menu); 72 73 JMenuItem openItem = new JMenuItem("Open"); 74 menu.add(openItem); 75 openItem.addActionListener(new FileOpenListener()); 76 77 JMenuItem exitItem = new JMenuItem("Exit"); 78 menu.add(exitItem); 79 exitItem.addActionListener(new ActionListener() 80 { 81 public void actionPerformed(ActionEvent event) 82 { 83 logger.fine("Exiting."); 84 System.exit(0); 85 } 86 }); 87 88 //使用標籤顯示圖像 89 label = new JLabel(); 90 add(label); 91 logger.exiting("ImageViewerFrame", "<init>"); 92 } 93 94 private class FileOpenListener implements ActionListener 95 { 96 public void actionPerformed(ActionEvent event) 97 { 98 logger.entering("ImageViewerFrame.FileOpenListener", "actionPerformed", event); 99 100 //設置文件選擇器 101 JFileChooser chooser = new JFileChooser(); 102 chooser.setCurrentDirectory(new File(".")); 103 104 //接受以.gif結尾的全部文件 105 chooser.setFileFilter(new javax.swing.filechooser.FileFilter() 106 { 107 public boolean accept(File f) 108 { 109 return f.getName().toLowerCase().endsWith(".gif") || f.isDirectory(); 110 } 111 112 public String getDescription() 113 { 114 return "GIF Images"; 115 } 116 }); 117 118 //顯示文件選擇器對話框 119 int r = chooser.showOpenDialog(ImageViewerFrame.this); 120 121 // 若是圖像文件被接受,將其設置爲標籤的圖標 122 if (r == JFileChooser.APPROVE_OPTION) 123 { 124 String name = chooser.getSelectedFile().getPath(); 125 logger.log(Level.FINE, "Reading file {0}", name); 126 label.setIcon(new ImageIcon(name)); 127 } 128 else logger.fine("File open dialog canceled."); 129 logger.exiting("ImageViewerFrame.FileOpenListener", "actionPerformed"); 130 } 131 } 132 } 133 134 /** 135 * 用於在窗口中顯示日誌記錄的處理程序。 136 */ 137 class WindowHandler extends StreamHandler//繼承 138 { 139 private JFrame frame; 140 141 public WindowHandler() 142 { 143 frame = new JFrame(); 144 final JTextArea output = new JTextArea(); 145 output.setEditable(false); 146 frame.setSize(200, 200); 147 frame.add(new JScrollPane(output)); 148 frame.setFocusableWindowState(false); 149 frame.setVisible(true); 150 setOutputStream(new OutputStream() 151 { 152 public void write(int b) 153 { 154 } // not called 155 156 public void write(byte[] b, int off, int len) 157 { 158 output.append(new String(b, off, len)); 159 } 160 }); 161 } 162 163 public void publish(LogRecord record) 164 { 165 if (!frame.isVisible()) return; 166 super.publish(record); 167 flush(); 168 } 169 }
1)條件斷點(有必定條件的斷點):在Eclipse Java 編輯區的行頭雙擊就會獲得一個斷點,代碼會運行到此處時中止。
在斷點處點擊鼠標右鍵,選擇最後一個「Breakpoint Properties」。
2)變量斷點:在變量的值初始化,或是變量值改變時能夠中止。
3)方法斷點:方法斷點就是將斷點打在方法的入口處。
4)異常斷點:當異常發生時,代碼會停在異常發生處。
5)從新調試:回退時,請在須要回退的線程方法上點右鍵,選擇「Drop to Frame」。
6)單步執行程序
7)檢查變量
8)改變變量值
實驗總結:
1.異常
全部異常類型都是 Throwable 類的子類,它包含Exception類和Error類,Exception又包括checked exception和unchecked exception。
unchecked exception:Java編譯器不要求對未檢查異常必定捕獲或拋出,能夠不作處理。此類異常一般是在邏輯上有錯誤,能夠經過修改代碼避免。在eclipse中(保存即編譯)編譯後此類異常發生處會報錯。
checked exception:Java編譯器要求對檢查異常必須捕獲或拋出,代碼邏輯沒有錯誤,但程序運行時會由於IO等錯誤致使異常,你在編寫程序階段是預料不到的。若是不處理這些異常,程序未來確定會出錯。因此編譯器會提示你要去捕獲並處理這種可能發生的異常,不處理就不能經過編譯。
2.Throwable類的堆棧信息跟蹤。
堆棧跟蹤是一個方法調用過程的立標,它包含了程序執行過程當中方法的調用的特定位置。可使用Throwable的接口獲取堆棧信息,進行分析調用狀況。
3.斷言
assert。在程序開發過程當中使用它建立一個斷言(assertion),它的
語法形式有以下所示的兩種形式:
一、assert condition;
這裏condition是一個必須爲真(true)的表達式。若是表達式的結果爲true,那麼斷言爲真,而且無任何行動
若是表達式爲false,則斷言失敗,則會拋出一個AssertionError對象。這個AssertionError繼承於Error對象,
而Error繼承於Throwable,Error是和Exception並列的一個錯誤對象,一般用於表達系統級運行錯誤。
二、asser condition:expr;
這裏condition是和上面同樣的,這個冒號後跟的是一個表達式,一般用於斷言失敗後的提示信息,說白了,它是一個傳到AssertionError構造函數的值,若是斷言失敗,該值被轉化爲它對應的字符串,並顯示出來。
3.在本週學習了程序產生的異常以及如何解決程序中產生的異常。異常時在程序的執行過程當中所發生的非正常事件,它中斷指令的正常執行。所以在編寫代碼時須要及時處理這些錯誤。基本理解了異常的產生的緣由和解決方法。但對於斷言以及日誌等內容不太理解。所以在運行後面幾個相關程序時,對程序不是很理解。之後本身也會多練習程序去了解這些知識。