(一)理解什么是异常,异常处理机制的执行特点
1、设有一个数组存储一批英文单词,从键盘输入一个数n,输出数组中元素序号为n的单词。
import javax.swing.*; public class ExceptionTest1 { public static void main(String[] args) { String word[]={"good","bad","ok","bye"}; String s=JOptionPane.showInputDialog("请输入一个数:"); int n=Integer.parseInt(s); System.out.println(word[n]); } }
运行该程序,观察:
输入0 输出good
输入1 输出bad
输入2 输出ok
输入3 输出bye
2.输入4、5或-1,观察会产生什么异常,为什么会产生这样的异常?
输入4:Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 4
at ExceptionTest1.main(ExceptionTest1.java:9)
输入5:Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 4
at ExceptionTest1.main(ExceptionTest1.java:9)
输入-1:Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 4
at ExceptionTest1.main(ExceptionTest1.java:9)
数组下标越界异常。word数组只包含四个单词,因此下标应大于-1小于4,4、5、-1不符合要求,因此会出现异常。
3.输入a,观察会产生什么异常,为什么会产生这样的异常?
Exception in thread "main" java.lang.NumberFormatException: For input string: "a"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Integer.parseInt(Integer.java:668)
at java.base/java.lang.Integer.parseInt(Integer.java:786)
at ExceptionTest1.main(ExceptionTest1.java:8)
数字格式异常。a为字母,不是具体的数字,无法运用Integer.parseInt(s)函数。
2、为了控制异常的报错处理,利用try…catch进行异常处理
import javax.swing.*; public class ExceptionTest1 { public static void main(String[] args) { try{ String word[]={"good","bad","ok","bye"}; String s=JOptionPane.showInputDialog("请输入一个数:"); int n=Integer.parseInt(s); System.out.println(word[n]); } catch(NumberFormatException e){ System.out.println("要求输入整数"); } catch(ArrayIndexOutOfBoundsException e){ System.out.println("数组访问出界"); } } }
调试程序,理解异常处理的作用。
当输入0、1、2、3时,系统正常输出good、bad、ok、bye。由于ExceptionTest1类中加入了try…catch进行异常处理,当出现数组下标越界异常时,即出现当输入大于3或小于0的数时,系统输出“数组访问出界”,当输入非数字时,系统输出“要求输入整数”。
3、将以上两个catch部分内容删除,改用一个catch,其中,捕获的异常为Exception类,观察程序的运行变化。
catch(Exception e){
System.out.println("出现异常");
}
体会异常层次的继承关系。
修改以后,两种异常均会显示“出现异常”。
4、在程序的异常处理代码中加入finally部分,检查其代码在什么情况下将执行。
finally{
System.out.println("执行了finally块");
}
正常情况和异常情况均会执行finally块的内容吗?
均会执行finally块的内容
5、异常排序问题
将前面的3个catch均包含在程序中,如何排列?是否能将第3条的catch放在首位?为什么?
ExceptionTest1.java:15: 错误: 已捕获到异常错误NumberFormatException
catch(NumberFormatException e){
^
ExceptionTest1.java:18: 错误: 已捕获到异常错误ArrayIndexOutOfBoundsException
catch(ArrayIndexOutOfBoundsException e){
^
2 个错误
(二)自定义异常类、抛出异常和捕获异常
1、实验要求
2、程序模板:
按模板要求,将【代码1】~【代码8】替换为Java程序代码。
ExceptionExample.java
【代码1】// 类声明,声明一个Exception的子类NoLowerLetter { public void print() { System.out.printf("%c",'#'); } } 【代码2】 // 类声明,声明一个Exception的子类NoDigit { public void print() { System.out.printf("%c",'*'); } } class People { void printLetter(char c) throws NoLowerLetter { if(c<'a'||c>'z') { NoLowerLetter noLowerLetter=【代码3】 // 创建NoLowerLetter类型对象 【代码4】 // 抛出noLowerLetter } else { System.out.print(c); } } void printDigit(char c) throws NoDigit { if(c<'1'||c>'9') { NoDigit noDigit=【代码5】 // 创建NoDigit()类型对象 【代码6】 // 抛出noDigit } else { System.out.print(c); } } } public class ExceptionExample { public static void main (String args[ ]) { People people=new People( ); for(int i=0;i<128;i++) { try { people.printLetter((char)i); } 【代码7】 // 捕获NoLowerLetter类异常 { e.print(); } } for(int i=0;i<128;i++) { try { people.printDigit((char)i); } 【代码8】 // 捕获NoDigit类异常 { e.print( ); } } } }
3、给出程序的运行结果,并简单描述程序的功能。
结果:
#################################################################################################abcdefghijklmnopqrstuvwxyz#####*************************************************123456789**********************************************************************
功能:找出编码在前128的字母和数字
4、实验指导
5、下述代码输出的结果是什么?请简单说明。
try{ for(int i=0;i<128;i++) { people.printLetter((char)i); } } catch(NoLowerLetter e) { e.print(); }
输出结果:#
(三)编写程序
在三角形中任何两边之和总大于第三边,三角形类Triangle必须遵循这一规则。
1、实验要求:
如下所示:
public Triangle(double side1,double side2,double side3)
throws IllegalTriangleException
{
//implement it
}
如果在main方法中不处理异常,可以把IllegalTriangleException抛给JVM来处理。
class IllegalTriangleException extends Exception{ IllegalTriangleException(){ super();} IllegalTriangleException(String message){ super(message);} } class Triangle{ public Triangle(double side1,double side2,double side3) throws IllegalTriangleException { if(side1+side2>side3&&side1+side3>side2&&side2+side3>side1){ System.out.println("可以形成三角形");} else{ IllegalTriangleException m=new IllegalTriangleException(); thow m;} //implement it } } public class Tester { public static void main (String args[ ]){ Triangle t=new Triangle(3,1,6); } }
(四)下面程序编译能通过,但由于程序中要打开的文件zxf1.txt不存在,因此运行该程序时抛出了FileNotFoundException异常。
此程序说明了对检查型异常(Checked Exception)的一种处理方法:向上抛出异常。
import java.io.RandomAccessFile; import java.io.FileNotFoundException; import java.io.IOException; public class ExceptionTest { public static void main(String[] args) throws FileNotFoundException,IOException { RandomAccessFile file=new RandomAccessFile(“zxf1.txt”,”r”); for(int i=0;i<35;i++) { System.out.print((char)file.readByte()); } file.close(); } }
对上面的代码进行改写,通过try-catch-finally块处理异常。
注意:catch语句的排列顺序应该是从特殊到一般。例如:本例中捕获FileNotFoundException的catch块放到前面,更一般的IOException异常捕获的catch块放到后面。
import java.io.RandomAccessFile; import java.io.FileNotFoundException; import java.io.IOException; public class ExceptionTest { public static void main(String[] args) { try{RandomAccessFile file=new RandomAccessFile("zxf1.txt","r"); for(int i=0;i<35;i++) { System.out.print((char)file.readByte()); } file.close(); } catch(FileNotFoundException e){ System.out.println("FileNotFoundException error!"); } catch(IOException e){ System.out.println("IOException error!"); } finally{ System.out.println("执行了finally块"); } } }