本章目标
了解异常的基本概念
掌握异常的基本处理格式
掌握异常类的继承结构
掌握Java的异常处理机制
异常
异常是导致程序中断运行的一种指令流,如果不对异常进行正确的处理,则可能导致程序的中断执行,造成不必要的损失,所以在程序的设计中必须要考虑各种异常的发生,并正确的做好相应的处理,这样才能保证程序正常的执行
认识异常
public class ExceptionDemo01 {
public static void main(String[] args) {
System.out.println("********** 计算开始 **********");
int i = 10;//定义整型变量
int j = 0;//定义整型变量
int temp = i/j;//此处会产生异常
System.out.println("两个数字相除结果:"+temp);
System.out.println("********** 计算结果 **********");
}
/* 结果:
* ********** 计算开始 **********
* Exception in thread "main" java.lang.ArithmeticException: / by zero
* at J020701.ExceptionDemo01.main(ExceptionDemo01.java:8)
* */
}
异常处理格式
try{
// 有可能出现异常的语句
}catch(异常类 异常对象){
// 编写异常的处理语句
}[ catch(异常类 异常对象){
// 编写异常的处理语句
} catch(异常类 异常对象){
// 编写异常的处理语句
} …. ]
[finally{
一定会运行到的程序代码 ;
}]
对异常进行捕捉
import java.util.Scanner;
public class ExceptionDemo02 {
public static void main(String[] args) {
System.out.println("********** 计算开始 **********");
int i = 10;//定义整型变量
int j = 0;//定义整型变量
try{
int temp = i/j;//此处会产生异常
System.out.println("两个数字相除结果:"+temp);//此代码不再执行
System.out.println("~~~~~~~~~~~~~~~~");//此代码不再执行
}catch(ArithmeticException e){//捕捉算术异常
System.out.println("出现异常了:"+e);//出现异常执行异常处理语句
}
System.out.println("********** 计算结果 **********");
}
/* 结果:
* ********** 计算开始 **********
* 出现异常了:java.lang.ArithmeticException: / by zero
* ********** 计算结果 **********
* */
}
程序执行流程
异常的统一出口 —— finally
import java.util.Scanner;
public class ExceptionDemo03 {
public static void main(String[] args) {
System.out.println("********** 计算开始 **********");
int i = 10;//定义整型变量
int j = 0;//定义整型变量
try{
int temp = i/j;//此处会产生异常
System.out.println("两个数字相除结果:"+temp);//此代码不再执行
System.out.println("~~~~~~~~~~~~~~~~");//此代码不再执行
}catch(ArithmeticException e){//捕捉算术异常
System.out.println("出现异常了:"+e);//出现异常执行异常处理语句
}finally{//异常的统一出口
System.out.println("不管是否出现异常,都执行代码");
}
System.out.println("********** 计算结果 **********");
}
/* 结果:
* ********** 计算开始 **********
* 出现异常了:java.lang.ArithmeticException: / by zero
* 不管是否出现异常,都执行代码
* ********** 计算结果 **********
* */
}
有多个异常的程序
import java.util.Scanner;
public class ExceptionDemo04 {
public static void main(String[] args) {
System.out.println("********** 计算开始 **********");
int i = 0;//定义整型变量
int j = 0;//定义整型变量
try{
String str1 = new Scanner(System.in).next();//接收第 1 个参数
String str2 = new Scanner(System.in).next();//接收第 2 个参数
i = Integer.parseInt(str1);//将第 1 个参数由字符串变为整型
j = Integer.parseInt(str2);//将第 2 个参数由字符串变为整型
int temp = i/j;//此处会产生异常
System.out.println("两个数字相除结果:"+temp);//此代码不再执行
System.out.println("~~~~~~~~~~~~~~~~");//此代码不再执行
}catch(ArithmeticException e){//捕捉算术异常
System.out.println("出现异常了:"+e);//出现异常执行异常处理语句
}
System.out.println("********** 计算结果 **********");
}
/* 结果:
* ********** 计算开始 **********
* 10
* 0
* 出现异常了:java.lang.ArithmeticException: / by zero
* ********** 计算结果 **********
* or
* *********** 计算开始 **********
* 10
* 2
* 两个数字相除结果:5
* ~~~~~~~~~~~~~~~~
* ********** 计算结果 **********
* */
}
程序的异常
以上的程序实际上产生了三个比较明显的异常
——数组超出绑定异常:ArrayIndexOutOfBoundsException
——数字格式化异常:NumberFormatException
——算术异常:ArithmeticException
——此时如果要想保持程序的执行争取,就必须同时对三个异常进行处理,所以此时的catch语句应该有三个,以分别处理不同的异常。
捕捉多个异常
import java.util.Scanner;
public class ExceptionDemo05 {
public static void main(String[] args) {
System.out.println("********** 计算开始 **********");
int i = 0;//定义整型变量
int j = 0;//定义整型变量
try{
String str1 = new Scanner(System.in).next();//接收第 1 个参数
String str2 = new Scanner(System.in).next();//接收第 2 个参数
i = Integer.parseInt(str1);//将第 1 个参数由字符串变为整型
j = Integer.parseInt(str2);//将第 2 个参数由字符串变为整型
int temp = i/j;//此处会产生异常
System.out.println("两个数字相除结果:"+temp);//此代码不再执行
System.out.println("~~~~~~~~~~~~~~~~");//此代码不再执行
}catch(ArithmeticException e){//捕捉算术异常
System.out.println("算术异常:"+e);//处理算术异常
}catch(NumberFormatException e){
System.out.println("数字转换异常:"+e);//处理数字转换异常
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("数组越界异常:"+e);//处理数组越界
}
System.out.println("********** 计算结果 **********");
}
/* 结果:
* ********** 计算开始 **********
* 12
* string
* 数字转换异常:java.lang.NumberFormatException: For input string: "string"
* ********** 计算结果 **********
* */
}
异常类的继承结构
在整个java的异常结构中,实际上有以下两个最常用的类:Exception、Error,这两个类全都是Throwable的子类
——Exception:一般表示的是程序中出现的问题,可以直接使用try…catch处理。
——Error:一般指的是JVM错误,程序中无法处理。
Java的异常处理机制
在整个java的异常处理中,实际上也是按照面向对象的方式进行处理,处理的步骤如下:
——一旦产生异常,则首先会产生一个异常类的实例化对象;
——在try语句中对此异常对象进行捕捉;
——产生的异常对象与catch语句中的各个异常类型进行匹配,如果匹配成功,则执行catch语句中的代码。
使用Exception处理其他异常
从之前学习过的对象多态性可以清楚的知道,所有的子类实例可以全部使用父类接收,那么就可以利用向上转型的概念,让所有的异常对象都使用Exception接收。
注意:在java中所有捕获范围小的异常,必须放在捕获大的异常之前。否则程序在编译的时候就会出现错误提示。
import java.util.Scanner;
public class ExceptionDemo06 {
public static void main(String[] args) {
System.out.println("********** 计算开始 **********");
int i = 0;//定义整型变量
int j = 0;//定义整型变量
try{
String str1 = new Scanner(System.in).next();//接收第 1 个参数
String str2 = new Scanner(System.in).next();//接收第 2 个参数
i = Integer.parseInt(str1);//将第 1 个参数由字符串变为整型
j = Integer.parseInt(str2);//将第 2 个参数由字符串变为整型
int temp = i/j;//此处会产生异常
System.out.println("两个数字相除结果:"+temp);//此代码不再执行
System.out.println("~~~~~~~~~~~~~~~~");//此代码不再执行
}catch(ArithmeticException e){//捕捉算术异常
System.out.println("算术异常:"+e);//处理算术异常
}catch(NumberFormatException e){
System.out.println("数字转换异常:"+e);//处理数字转换异常
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("数组越界异常:"+e);//处理数组越界
}catch(Exception e){
System.out.println("其他异常:"+e);//处理其他异常
}
System.out.println("********** 计算结果 **********");
}
/* 结果:
* ********** 计算开始 **********
* 12
* string
* 数字转换异常:java.lang.NumberFormatException: For input string: "string"
* ********** 计算结果 **********
* */
}
import java.util.Scanner;
public class ExceptionDemo07 {
public static void main(String[] args) {
System.out.println("********** 计算开始 **********");
int i = 0;//定义整型变量
int j = 0;//定义整型变量
try{
String str1 = new Scanner(System.in).next();//接收第 1 个参数
String str2 = new Scanner(System.in).next();//接收第 2 个参数
i = Integer.parseInt(str1);//将第 1 个参数由字符串变为整型
j = Integer.parseInt(str2);//将第 2 个参数由字符串变为整型
int temp = i/j;//此处会产生异常
System.out.println("两个数字相除结果:"+temp);//此代码不再执行
System.out.println("~~~~~~~~~~~~~~~~");//此代码不再执行
}catch(Exception e){//异常捕获范围大
System.out.println("其他异常:"+e);//处理其他异常
}catch(ArithmeticException e){//错误,无法捕捉算术异常
System.out.println("算术异常:"+e);//处理算术异常
}
System.out.println("********** 计算结果 **********");
}
/* 结果:
* ********** 计算开始 **********
* Exception in thread "main" java.lang.Error: Unresolved compilation problem:
* Unreachable catch block for ArithmeticException. It is already handled by the catch block for Exception
* at J020701.ExceptionDemo07.main(ExceptionDemo07.java:20)
* ********** 计算结果 **********
* */
}
使用Exception处理异常
import java.util.Scanner;
public class ExceptionDemo08 {
public static void main(String[] args) {
System.out.println("********** 计算开始 **********");
int i = 0;//定义整型变量
int j = 0;//定义整型变量
try{
String str1 = new Scanner(System.in).next();//接收第 1 个参数
String str2 = new Scanner(System.in).next();//接收第 2 个参数
i = Integer.parseInt(str1);//将第 1 个参数由字符串变为整型
j = Integer.parseInt(str2);//将第 2 个参数由字符串变为整型
int temp = i/j;//此处会产生异常
System.out.println("两个数字相除结果:"+temp);//此代码不再执行
System.out.println("~~~~~~~~~~~~~~~~");//此代码不再执行
}catch(Exception e){//异常捕获范围大
System.out.println("其他异常:"+e);//处理其他异常
}
System.out.println("********** 计算结果 **********");
}
/* 结果:
* ********** 计算开始 **********
* 10
* 0
* 其他异常:java.lang.ArithmeticException: / by zero
********** 计算结果 **********
* */
}