實驗四 字符串和異常處理
【開發語言及實現平臺或實驗環境】Windows2000 或XP,JDK1.5以上版本與Eclipse集成開發環境
【實驗目的】
1.了解Java 中字符串和異常處理(exception)的作用。
2.掌握字符串操作、異常處理的設計方法。
【實驗要求】
理解系統異常處理的機制和定義異常的方法。
【知識要點】
1.錯誤與異常
在程序執行期間,會有許多意外的事件發生。例如,程序申請內存時沒有申請到、對象還未創建就被使用、死循環等,稱為運行錯誤。根據錯誤的性質將運行錯誤分為錯誤與異常兩種類型。
(1)錯誤
程序進入了死循環或內存溢出,這類現象稱為錯誤或致命性錯誤。錯誤只能在編程階段解決,運行時程序本身無法解決,只能依靠其它程序干預,否則會一直處于一種不正常的狀態。
(2)異常
運算時除數為0,或操作數超出數據范圍,打開一個文件時發現文件不存在,網絡連接中斷等等,這類運行錯誤現象稱為異常。對于異常情況,可在源程序中加入異常處理代碼,當程序出現異常時,由異常處理代碼調整程序運行流程,使程序仍可正常運行直到正常結束。
由于異常是可以檢測和處理的,所以產生了相應的異常處理機制。而錯誤處理一般由系統承擔。
對于一個應用軟件,異常處理機制是不可缺少的。程序員必須在程序中考慮每一個可能發生的異常情況并進行處理,以保證程序在任何情況下都能正常運行。事實證明,一個仔細設計了異常處理的程序,可以長時間的可靠運行,而不容易發生致命的錯誤,如程序被迫關閉、甚至系統終止等等。所以學會進行異常情況處理對于想編寫功能完善且具有實用價值的程序員來說是必不可少的。
2.異常發生的原因
(1)Java 虛擬機檢測到了非正常的執行狀態,這些狀態可能是由以下幾種情況引起的:
·表達式的計算違反了Java 語言的語義,例如整數被0 除。
·在載入或鏈接Java 程序時出錯。
·超出了某些資源限制,例如使用了太多的內存。
(2)Java 程序代碼中的throw 語句被執行。
(3)異步異常發生。異步異常的原因可能有:
·Thread 的stop 方法被調用。
·Java 虛擬機內部錯誤發生。
3.異常處理機制
發生異常后,怎么處理異常呢?Java 提供了異常處理機制來處理異常。分為兩個步驟:
(1)拋出異常
Java 是這樣規定的:當語義限制被違反時,將會拋出(throw)異常,即產生一個異常事件,生成一個異常對象,并把它提交給運行系統,再由運行系統尋找相應的代碼來處理異常。一個異常對象可以由Java 虛擬機來產生,也可以由運行的方法生成。異常對象中包含了異常事件類型、程序運行狀態等必要信息。
(2)捕獲異常
異常拋出后,運行時系統從生成異常對象的代碼開始,沿方法的調用棧進行查找,直到找到包含相應處理的方法代碼,并把異常對象交給該方法為止,這個過程稱為捕獲(catch)異常。
簡單說異常處理機制就是:當語義限制被違反時,將會拋出異常對象,并將引起程序流程從異常發生點轉移到程序員指定的處理異常方法代碼處進行異常處理。
4.了解異常對象的類型
在異常發生后,系統會產生一個異常事件,生成一個異常對象,有哪些異常對象呢?這些異常對象來自哪些類呢?
Java 中的異常類具有層次結構組織。其中,Throwable 類是Error 錯誤類和Exception 異常類的父類,它是Object 的直接子類。RuntimeException 運行時異常類是Exception 異常類的子類。如圖所示。
1.Exception 異常類的子類
(1)RuntimeException 運行時異常類,主要包括以下異常子類:
·ArithmeticException 算術異常類:表示遇到了異常的算術問題,例如被0 整除。
·ArrayStoreException 數組下標越界異常類:試圖把與數組類型不相符的值存人數組。
·ClassCastException 類型強制轉換異常類:試圖把一個對象的引用強制轉換為不合適的類型。
·IndexOutOfBoundsException 下標越界異常類:下標越界。
·NullPointerException 空指針異常類:試圖使用一個空的對象引用。
·SecurityException 違背安全原則異常類:檢測到了違反安全的行為。
(2)NoSuchMethodException 方法未找到異常
(3)java.awt.AWTException 圖形界面異常類
(4)java.io.IOException 輸入輸出異常類
·IOException:申請I/O 操作沒有正常完成。
·EOFException:在輸入操作正常結束前遇到了文件結束符。
·FileNotFoundException:在文件系統中,沒有找到由文件名字符串指定的文件。
(5)Exception 異常類的其它子類
·EmptyStackException:試圖訪問一個空堆棧中的元素。
·NoSuchFieldException:試圖訪問一個不存在的域。
·NoSuchMethodException:試圖訪問不存在的方法。
·ClassNotFoundException:具有指定名字的類或接口沒有被發現。
·CloneNotSupportedException:克隆一個沒有實現Cloneable 接口的類。
·IllegalAccessException:試圖用給出了完整的路徑信息的字符串加載一個類,但是當前正在執行的方法無法訪問指定類,因為該類不是public 類型或在另一個包中。
·InstantiationException:試圖使用Class 的newInstance 方法創建一個對象實例,但指定的對象沒有被實例化,因為它是一個接口、抽象類或者一個數組。
·InterruptedException:當前的線程正在等待,而另一個線程使用了Thread 的interrupt 方法中斷了當前線程。
2.Error 錯誤類的子類
(1) VirtualMachineError 虛擬機錯誤
·OutOfMemoryError 內存溢出錯誤
·StackOverflowError 棧溢出錯誤
(2) LinkageError 鏈接錯誤
·NoClassDefNotFoundError 類定義未找到錯誤
9、 java.awt.AWTError 圖形界面錯誤
【實驗內容1】字符串處理
1、當從鍵盤輸入為“good”,顯示為“好”,輸入其余字符,顯示為“不好”。
2、將從鍵盤輸入的字符串倒序打印輸出。
3、設定一個有大小寫字母的字符串和一個查找字符,使用String類的方法indexOf()來判斷在該字符串中對應字符出現的次數。
4、寫一個函數,求一個字符串的長度,在main函數中輸入字符串,并輸出其長度。
5、將字符串中的第m位進行替換,如果是大寫字母,則替換為小寫字母;如果是小寫字母,則替換為大寫字母;其他情況,則不變。
6、編寫一個應用程序,使用StringBuffer對象實現對字符串的編輯操作,包括:替換字符中的某些字符,刪除字符串中的某些字符,在字符串中插入或尾部加入新的字符串,翻轉字符串等。
7、接受用戶輸入的一個字符串和一個字符,把字符串中所有指定的字符刪除后輸出。
8、整理字符串將前后空白刪去。并把中間的多個空白保留一個。
9、(附加問題)編寫實現從兩字符串找出最長的相同字符序列的代碼。
【實驗內容2】異常處理
一、使用try…catch 語句處理異常
1.異常類型匹配的處理方式
(1)程序功能:首先說明" 這是一個異常處理的例子", 然后在程序中主動產生一個
ArithmeticException 類型被0 除的異常,并用catch 語句捕獲這個異常。最后通過
ArithmeticException 類的對象e 的方法getMessage 給出異常的具體類型并顯示出來。
(2)編寫使用 try…catch 語句處理異常的程序文件LX4_6.java,源代碼如下。
public class LX4_6{
public static void main(String[] arg3) {
System.out.println("這是一個異常處理的例子"n");
try {
int i=10;
i /=0;
}catch (ArithmeticException e) {
System.out.println("異常是:"+e.getMessage());
}
finally {
System.out.println("finally 語句被執行");
}
}
}
(3)編譯并運行程序,結果如圖4.7 所示。
注意:如果在catch 語句中聲明的異常類是Exception,catch 語句也能正確地捕獲,這是因為Exception 是ArithmeticException 的父類。如果不能確定會發生哪種情況的異常,那么最好指定catch的參數為Exception,即說明異常的類型為Exception。
2.異常類型不匹配的程序
(1)編寫一個catch 語句中聲明的異常類型不匹配的程序LX4_7.java,源代碼如下。
public class LX4_7{
public static void main(String[] args) {
System.out.println(“這是一個異常處理的例子"n”);
try {
int i=10;
i /=0;
}
catch (IndexOutOfBoundsException e) {
System.out.println("異常是:"+e.getMessage());
}
finally {
System.out.println("finally 語句被執行");
}
}
}
(2)編譯并運行程序LX4_7,結果如圖4.8 所示。
因為LX4_7 程序試圖捕獲一個異常類為IndexOutOfBoundsException 的異常,但發生的異常卻是ArithmeticException 類,所以,程序可以通過編譯但在運行時,系統會給出異常報告:報告所發生的但沒有被捕獲的異常。不過在此之前,其它語句和finally 語句將會被執行。
3.包含多個catch 子句的異常處理程序
(1)程序功能:在try 子句中設計兩個可能出現的異常,當a 為0 時會發生異常。另外一個是肯定的異常,因為數組c 的長度為1,定義c[42]是為法的。通過兩個catch 子句分別來捕獲異常。
(2)編寫包含多個catch 子句的LX4_8.java 程序,源代碼如下。
public class LX4_8{
public static void main(String[] args) {
try {
int a=args.length;
System.out.println(""na = "+a);
int b=42/a;
int c[]={1};
c[42]=99;
}
catch (ArithmeticException e) {
System.out.println("發生了被 0 除:"+e);
}
catch (ArrayIndexOutOfBoundsException e) {
System.out.println("數組下標越界:"+e);
}
}
}
(3)實驗下面兩種情況:
1)在程序運行時不輸入參數,則args.length 的值為0,這將引起一個被0 除異常。其結果如圖4.9 所示。
2)在運行程序時,輸入22,將不會引起被0除異常,但會引起一另一個異常即數組下標越界ArrayIndexOutOfBoundsException。因為整型數組只有一個元素c[0],程序中卻要
使用c[42],這將發生數組下標越界。運行結果如圖4.10 所示。
二、使用throw 語句拋出異常
1. throw 語句的作用
在上面的實驗中,可以發現,異常對象是Java 運行時由系統拋出的。拋出異常也可以通過使用throw 語句實現。throw 是Java 語言的關鍵字,用來告知編譯器此處要發生一個異常。throw 后面要跟一個新創建的異常類對象,用于指出異常的名稱和類型。
throw 語句格式為:<throw> <new> <異常對象名()>;
程序會在throw 語句處立即終止,轉向try…catch 尋找異常處理方法,不再執行throw 后面的語句。
2. throw 語句的使用
(1)編寫帶有throw 語句的程序TC5.java,源代碼如下。
public class LX4_9 {
static void throwProcess() {
try {
throw new NullPointerException("空指針異常");
}
catch (NullPointerException e) {
System.out.println(""n 在 throwProcess 方法中捕獲一個"+e.getMessage());
throw e;
}
}
public static void main(String args[]) {
try {
throwProcess();
}
catch (NullPointerException e) {
System.out.println("再次捕獲:"+e);
}
}
}
(2)編譯并運行程序,結果如圖4.11 所示。
(3)程序執行流程
程序首先調用throwProcess 方法,明確地拋出了一個NullPointerException 異常并將其命名為“空指針異常”。然后程序流程將轉向throwProcess 方法中的catch 子句,輸出一條信息。throwProcess方法的catch 子句又拋出了一個同樣的異常e。然后結束throwProcess 方法的調用,執行main 方法中的catch 子句,再次捕獲這個異常。
三、使用throws 子句
1.throws 子句的作用
throws 子句一般用來表明在使用該方法時可能拋出異常但不捕獲的異常。異常由系統來處理。
throws 子句也可以指出拋出異常是RuntimeException 或自定義異常類,即異常的類型,以便準備調用其它方法捕獲它,這種情況一般需要兩個方法來分別處理拋出異常和處理異常。
2.只是在方法中拋出異常的程序
對于程序中無法處理的異常,可以使用throws 子句在方法中拋出異常交由系統處理。
(1)程序功能:在程序中打開文件a3.txt,因為該文件可能不存在或路徑不對,所以存在IOException 類型異常的可能,因此這里使用throws 來拋出異常。
(2)編寫只是拋出異常的程序文件LX4_10.java,源代碼如下。
import java.io.*;
public class LX4_10
{
public static void main (String args[]) throws IOException
{
FileInputStream fis = new FileInputStream("a3.txt");
}
}
(3)編譯并運行程序,如果該文件在當前目錄中不存在,將由系統自動給出異常報告,如圖4.12所示。
3.帶有捕獲處理的throws 子句
(1)程序功能:在這個程序中的mathod 方法中使用throws 子句拋出異常,在main 方法中捕獲處理異常。
(2)TC6.java,源代碼如下。
import java.io.*;
public class LX4_11{
static void mathod() throws IllegalAccessException {
System.out.println(""n 在 mathod 中拋出一個異常");
throw new IllegalAccessException();
}
public static void main(String args[]) {
try {
mathod();
}catch (IllegalAccessException e) {
System.out.println("在 main 中捕獲異常:"+e);}
}
}
(3)編譯并運行程序,結果如圖4.13 所示。
四、使用finally 子句
1. finally 子句的作用
當一個異常被拋出時,程序的執行流程就不再是連續的了,會跳過某些語句,甚至會由于沒有與之匹配的catch 子句而過早地返回,結束程序的運行。為了確保一段代碼不管發生什么異常都能被執行,可以使用finally 子句。每個try 語句至少都要有一個與之相配的catch 或finally 子句。
從一個方法中返回到調用它的另外一個方法,可以通過return 語句或通過一個沒有被捕獲的異常,但finally 子句總是在返回前被執行。
2.創建使用finally 子句的程序文件LX4_12.java。
(1)程序功能:在類LX4_12 的mathodA 方法中使用try 子句捕獲異常,使用finally 子句處理異常。在類LX4_11 的main 方法中使用try 子句捕獲mathodA 異常,
(2)編寫LX4_12.java 程序,源代碼如下。
class LX4_12{
static void mathodA() {
try {
System.out.println(""nmathodA 拋出一個異常");
throw new RuntimeException();
}finally {
System.out.println("執行 mathodA 的 finally");}
}
static void mathodB() {
try{
System.out.println("mathodB 正常返回");
return;
}finally {
System.out.println("執行 mathodB 的 finally");}
}
public static void main(String args[]) {
try {
mathodA();
} catch (Exception e) {
mathodB(); }
}
}
(3)編譯并運行該程序,結果如圖4.14 所示。
【思考題】
什么是異常?異常處理機制有什么作用?異常處理有哪些方式。
posted on 2010-04-15 14:38 libifeng 閱讀(1809) 評論(0) 編輯 收藏 所屬分類: Java實驗指導書