第十一讲 Java中的异常处理
主要内容 异常和异常处理的初步认识 Java中异常的封装 异常处理try/catch/finally 异常的生成再认识 |
异常处理是Java中唯一正式的错误报告机制。
异常和异常处理的初步认识
什么是异常?
一个程序是可行的,需要编译成功和运行无错两方面的配合。
异常(Exception)就是程序执行过程中意想不到的情况。
class Excep{
public int div(int a,int b){
return a/b;
}
}
class TestExcep{
public static void main(String[] aa){
Excep ec=new Excep();
ec.div(5,0);
System.out.println("OK");
}
}
结论:
² 编译成功的程序未必可以正确运行。
如:除以零、打开一个不存在的文件、网络连接中断、数组下标越界、正在加载的类文件丢失等。
² 不能正确运行,意味产生了异常。
什么是异常处理?
如果对异常不进行处理,JVM就会显示出错信息,并中止程序执行。
异常处理是一种处理异常的机制。在程序中给出另一段(多段)错误处理的代码,当JVM发现异常时,转至该段代码执行。
异常的封装
异常的封装
Java中,异常是以类的形式封装的。
² 程序中可处理的异常:定义了程序中遇到的轻微的错误条件。
² 错误异常:定义了程序中不能恢复的严重错误条件。如内存溢出、类文件格式错误等。这一类错误程序无法处理。
编译时受检的异常
受检异常(Checked Exception)
在编译时被能Java编译器检测到的异常。
² RuntimeException之外的Exception都是受检异常。
² 受检异常必须在编译时进行处理。
非受检异常(Unchecked Exception)
在编译时不能检测到的异常,包括:
² RuntimeException的所有子类异常。
² Error异常。
获得的异常的有关信息
Exception的方法可用来获取当前异常的信息
public String getMessage()
返回描述当前异常性质的简略信息
public String toString()
返回描述当前异常类和异常性质的信息
public void printStackTrace()
在当前的标准输出上输出错误信息(错误异常类、错误性质、发生错误的类和方法)
思考 1. 通过编译的程序运行时会产生异常吗? 2. 程序运行时产生的异常类是? 3. 欲打开一个文件,发现文件不存在,这是什么异常? 4. 文件相关的异常是受检还是非受检异常? 5. 程序无法处理的异常是? |
异常处理
有两种异常处理方式:捕捉异常、转移异常
捕捉异常方式的异常处理
对受检异常、运行时异常、主动抛出的异常均适用
try-catch捕捉异常处理语句
try{ …… } catch(ExceptionType name){ …… } |
流程分析说明:
² 生成异常,执行过程中遇到异常,自动产生一个对应异常类的对象
² 抛出异常,将生成的异常对象提交给JVM
² 捕获异常,JVM寻找能处理这一异常的代码,并将当前异常对象作为参数传递过去,交由处理。
练习:给上例加入异常处理,发生异常时可显示异常的基本信息。
思考 1. 如果catch后给出空语句{},情形会是怎样? 2. 如果JVM找不到对应的异常处理代码,会是怎样? 3. 异常没有发生,catch段会执行到吗? 4. 异常发生了,try体内产生异常语句的后续语句,有机会继续执行吗? |
练习:编译、修改并执行以下程序,以创建磁盘文件。
import java.io.*;
class CreateFile{
public static void main(String[] aa){
File f1=new File("d://ok.txt");
f1.createNewFile();
System.out.println(f1+" have been created.");
}
}
完整的try-catch-finally语句
try{ ... } catch (ExceptionType1 name) { …… } catch (ExceptionType2 name) { …… } …… finally { …… } |
² 具体的异常放在前,一般性的放在后
² 无论是否有异常产生,finally后的语句块都被执行。
² 通常可用finally语句来做清理操作,比如关闭一个文件或把一个变量重新设为恰当的值。
转移异常方式的异常处理
在类的成员方法中,可通过throws短语抛出异常。
适用于需要强制进行异常捕捉、而并不想做具体的异常处理的情况。
如:
import java.io.*;
class CreateFile{
public static void main(String[] aa) throws IOException{
File f1=new File("d://ok.txt");
f1.createNewFile();
System.out.println(f1+" have been created.");
}
}
例中如果缺少throws IOException,程序将不能通过编译。因为File类的createNewFile()方法要求进行强制异常捕捉。
说明:如果一个方法转移了异常,调用该方法的方法需要异常处理或转移异常。
练习:对Excep类中的方法div设置成转移异常,试修改程序编译运行。
异常的生成再认识*
运行时自动生成
运行时虚拟机发现异常时,自动生成异常对象。
异常抛出显式生成异常
throw Throwable类对象
如:
thrownew ArithmeticException();
或:
ArithmeticException e=new ArithmeticExption();
throw e;
作用:故意抛出一个异常。(抛给调用者,一级一级抛出)
示例:分析程序运行结果。
class Throw_Test {
static void throw_something() {
System.out.println(1);
throw new ArithmeticException();
}
public static void main (String[] args) {
try {
throw_something();
}
catch (ArithmeticException e) {
System.out.println(3);
}
}
}
说明:
[1]主动抛出的异常在虚拟机运行时发现,编译时不受检。
[2]Throw语句后不可有别的语句,否则会出现编译错误:“unreachable statement”
异常处理总结 ² 受检异常必须得到处理程序才可通过编译。 ² 对不可靠的程序块捕捉运行出错信息,以增强程序的强壮性。 |
练习:交互输入若干个数,求其和,直到结束标志999为止。请利用try…catch控制用户输入非整数(提示:非整数时,在Integer.parseInt转换时会发生NumberFormatException异常)。
import javax.swing.JOptionPane;
class TestE2{
public static void main(String[] aa){
System.out.println("sum="+sum);
}
}