本博客仅为个人学习记录,查看标准答案请忽视个人作业,个人作业仅为我自己比对用。
实验内容:
(一)理解什么是异常,异常处理机制的执行特点
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
- 输入4、5或-1,观察会产生什么异常,为什么会产生这样的异常?
ArrayIndexOutOfBoundsException数组访问出界异常
因为输入的数超出了数组的长度。
- 输入a,观察会产生什么异常,为什么会产生这样的异常?
NumberFormatException数字格式异常
原因是程序要求s为int类型的数据,而a不为int类型,因此产生数字格式异常
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("数组访问出界");
}
}
}
- 调试程序,理解异常处理的作用。
输入4、5或-1,由于捕获了ArrayIndexOutOfBoundsException异常,输出“数组访问出界”
输入a,由于捕获了NumberFormatException异常,输出“要求输入整数”
异常处理可以使编译器来代替程序员考虑各种错误,这为处理某一类错误提供了一个很有效的方法,使编程效率大大提高。
3、将以上两个catch部分内容删除,改用一个catch,其中,捕获的异常为Exception类,观察程序的运行变化。
catch(Exception e){
System.out.println("出现异常");
}
- 体会异常层次的继承关系。
由于输入4、5、-1或者a时,都捕获的Exception类异常,程序输出 "出现异常"
Exception程序可处理的异常包括非运行时异常和运行时异常, try catch语句捕获多个异常时,子类异常在前捕获,父类异常在后捕获。
4、在程序的异常处理代码中加入finally部分,检查其代码在什么情况下将执行。
finally{
System.out.println("执行了finally块");
}
- 正常情况和异常情况均会执行finally块的内容吗?
正常情况和异常情况均会执行
5、异常排序问题
将前面的3个catch均包含在程序中,如何排列?是否能将第3条的catch放在首位?为什么?
异常排序的顺序应该为:
NumberFormatException
ArrayIndexOutOfBoundsException
Exception
不可以将第3条的catch放在首位,因为异常捕获的顺序是从前到后的,如果Exception排在前面,那么就无法捕获NumberFormatException和ArrayIndexOutOfBoundsException了。
最终程序:
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("数组访问出界");
}
catch(Exception e){
System.out.println("出现异常");
}
finally{
System.out.println("执行了finally块");
}
}
}
(二)自定义异常类、抛出异常和捕获异常
1、实验要求
- 声明定义两个Exception的异常子类:NoLowerLetter类和NoDigit类;
- 声明一个People类,该类中
- void printLetter(char c)方法抛出NoLowerLetter异常类对象;
- void printDigit(char c)方法抛出NoDigit异常类对象。
2、程序模板:
按模板要求,将【代码1】~【代码8】替换为Java程序代码。
ExceptionExample.java
class NoLowerLetter extends Exception// 类声明,声明一个Exception的子类NoLowerLetter
{
public void print()
{
System.out.printf("%c",'#');
}
}
class NoDigit extends Exception // 类声明,声明一个Exception的子类NoDigit
{
public void print()
{
System.out.printf("%c",'*');
}
}
class People
{
void printLetter(char c) throws NoLowerLetter
{
if(c<'a'||c>'z')
{
NoLowerLetter noLowerLetter=new NoLowerLetter(); // 创建NoLowerLetter类型对象
throw(noLowerLetter); // 抛出noLowerLetter
}
else
{
System.out.print(c);
}
}
void printDigit(char c) throws NoDigit
{
if(c<'1'||c>'9')
{
NoDigit noDigit=new NoDigit(); // 创建NoDigit()类型对象
throw(noDigit); // 抛出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);
}
catch(NoLowerLetter e) // 捕获NoLowerLetter类异常
{
e.print();
}
}
for(int i=0;i<128;i++)
{
try
{
people.printDigit((char)i);
}
catch(NoDigit e)// 捕获NoDigit类异常
{
e.print( );
}
}
try{
for(int i=0;i<128;i++)
{
people.printLetter((char)i);
}
}
catch(NoLowerLetter e)
{
e.print();
}
}
}
- 给出程序的运行结果,并简单描述程序的功能。
#################################################################################################abcdefghijklmnopqrstuvwxyz#####*************************************************123456789**********************************************************************
程序判断在0到127asc码范围内的字符如果不在c<'a'||c>'z'的范围内就抛出noLowerLetter异常即打印#代替字符、判断在0到127asc码范围内的字符如果不在c<'1'||c>'9'的范围内就抛出NoDigit异常即打印*代替字符。
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();
}
此段代码输出#,这是因为循环在try语句内且循环第一个数就出现了异常,捕获NoLowerLetter类错误之后try语句结束循环也不再继续进行。
(三)编写程序
在三角形中任何两边之和总大于第三边,三角形类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 {
public IllegalTriangleException() {
super("The triangle is not legal ! ");
}
}
class Triangle {
double side1, side2, side3;
public Triangle(double side1, double side2, double side3) throws IllegalTriangleException {
if (side1 + side2 > side3 && side1 + side3 > side2 && side2 + side3 > side1) {
this.side1 = side1;
this.side2 = side2;
this.side3 = side3;
} else
throw new IllegalTriangleException();
}
}
public class Tester {
public static void main(String args[]) throws IllegalTriangleException {
Triangle t1 = new Triangle(3.0, 4.0, 5.0);
Triangle t2 = new Triangle(9.0, 1.0, 1.0);
}
}
个人作业:
class IllegalTriangleException extends Exception{
public IllegalTriangleException(){
super();
}
public IllegalTriangleException(String message){
super(message);
}
}
class Triangle
{
public Triangle(double side1,double side2,double side3)
throws IllegalTriangleException
{
if(side1+side2<side3||side1+side3<side2||side3+side2<side1)
throw new IllegalTriangleException("不能构成三角形");
System.out.println("可以构成三角形");
}
}
public class Tester {
public static void main(String[] args) {
try {
Triangle triangle=new Triangle(3,1,5);
}
catch(IllegalTriangleException e) {
System.out.println(e.getMessage());
}
}
}
(四)下面程序编译能通过,但由于程序中要打开的文件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) throws FileNotFoundException,IOException
{
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("文件未找到");
}
catch(IOException e) {
System.out.println("出现异常");
}
finally{
System.out.println("执行了finally块");
}
}
}