(一)理解什么是异常,异常处理机制的执行特点
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、1、2、3,检查输出结果?
输入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放在首位?为什么?
- NumberFormatException、ArrayIndexOutOfBoundsException放在前面。不能将第3条的catch放在首位,会出现报错:
ExceptionTest1.java:15: 错误: 已捕获到异常错误NumberFormatException
catch(NumberFormatException e){
^
ExceptionTest1.java:18: 错误: 已捕获到异常错误ArrayIndexOutOfBoundsException
catch(ArrayIndexOutOfBoundsException e){
^
2 个错误
(二)自定义异常类、抛出异常和捕获异常
1、实验要求
- 声明定义两个Exception的异常子类:NoLowerLetter类和NoDigit类;
- 声明一个People类,该类中
- void printLetter(char c)方法抛出NoLowerLetter异常类对象;
- void printDigit(char c)方法抛出NoDigit异常类对象。
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、实验指导
- Java运行环境定义了许多异常类(Exception的子类),当对应的异常发生时,就用相应的异常类创建一个异常对象,并等待处理。可以扩展Exception类定义自己的异常类,然后规定哪些方法产生这样的异常。
- 一个方法在声明时可以使用throws关键字声明抛出所要产生的若干个异常,并在该方法的方法体中具体给出产生异常的操作,即用相应的异常类创建对象,该方法抛出所创建的异常对象来结束方法的执行。程序必须在try…catch块语句中调用抛出异常的方法。
5、下述代码输出的结果是什么?请简单说明。
try{
for(int i=0;i<128;i++)
{
people.printLetter((char)i);
}
}
catch(NoLowerLetter e)
{
e.print();
}
输出结果:#
(三)编写程序
在三角形中任何两边之和总大于第三边,三角形类Triangle必须遵循这一规则。
1、实验要求:
- 创建一个IllegalTriangleException类继承Exception类
- 在空参构造函数中调用父类的构造函数Exception(String message)
- 创建一个Triangle类,编写Triangle类的构造方法,如果创建的三角形违反了这一规则,抛出一个IllegalTriangleException异常对象。
如下所示:
public Triangle(double side1,double side2,double side3)
throws IllegalTriangleException
{
//implement it
}
- 创建一个测试类Tester,测试类和方法。
如果在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块");
}
}
}