博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
异常的基本概念
阅读量:4331 次
发布时间:2019-06-06

本文共 9489 字,大约阅读时间需要 31 分钟。

目标:

1)异常基本概念,

2)处理异常基本格式

3)异常继承结构

4)掌握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 methoud.ThisDemo06.main(ThisDemo06.java:8)

处理异常

每当异常产生,会在程序中产生一个异常化的实例化对象,之后使用此对象与catch中的异常类型相互匹配,

如果匹配成功,则执行catch语句中内容,如果匹配不成功,向下继续匹配。如果都无法匹配,程序会中断执行。

异常处理格式:

package methoud;public class ThisDemo06{    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
********** 计算结束 ***********

以上是基本异常处理过程,try-catch,try捕获异常,出现异常后不再执行,而是跳到catch语句执行,处理异常。

当然,异常也可以设置统一出口,使用finally语句,无论是否发生异常都会执行。

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
不管是否出现异常,都执行此代码
********** 计算结束 ***********

以上只是处理一个异常,如果同时有多个异常呢?

修改代码,通过初始化参数,输入i和j。

package methoud;public class ThisDemo06{    public static void main(String args[]){        System.out.println("********** 计算开始 ***********") ;        int i = 0 ;        // 定义整型变量        int j = 0 ;            // 定义整型变量        try{            String str1 = args[0] ;        // 接收第一个参数            String str2 = args[1] ;        // 接收第二个参数            i = Integer.parseInt(str1) ;    // 将第一个参数由字符串变为整型            j = Integer.parseInt(str2) ;    // 将第二个参数由字符串变为整型            int temp = i / j ;    // 此处产生了异常            System.out.println("两个数字相除的结果:" + temp) ;            System.out.println("----------------------------") ;        }catch(ArithmeticException e){    // 捕获算术异常            System.out.println("出现异常了:" + e) ;        }        System.out.println("********** 计算结束 ***********") ;    }};

产生异常:

********** 计算开始 ***********Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0    at methoud.ThisDemo06.main(ThisDemo06.java:9)

实际上,数据是交给用户输入的,要是用户输入不正确,可能会发生三个问题:

1)如果没有输入参数,或者参数输入不够。

2)如果现在输入的参数是字母不是数字。

3)算数异常,如果被整除的是0.

要想保证程序正确执行,需要三个异常进行处理。使用三个catch语句。

public class ExceptionDemo05{    public static void main(String args[]){        System.out.println("********** 计算开始 ***********") ;        int i = 0 ;        // 定义整型变量        int j = 0 ;            // 定义整型变量        try{            String str1 = args[0] ;        // 接收第一个参数            String str2 = args[1] ;        // 接收第二个参数            i = Integer.parseInt(str1) ;    // 将第一个参数由字符串变为整型            j = Integer.parseInt(str2) ;    // 将第二个参数由字符串变为整型            int temp = i / j ;    // 此处产生了异常            System.out.println("两个数字相除的结果:" + temp) ;            System.out.println("----------------------------") ;        }catch(ArithmeticException e){    // 捕获算术异常            // System.out.println("算术异常:" + e) ;            e.printStackTrace() ;        }catch(NumberFormatException e){    // 捕获数字转换异常            System.out.println("数字转换异常:" + e);        }catch(ArrayIndexOutOfBoundsException e){    // 捕获数组越界异常            System.out.println("数组越界异常:" + e) ;        }        System.out.println("********** 计算结束 ***********") ;    }};

以上只是一个很小的程序都要处理三个异常。当然还有可能有更多异常。那么处理更麻烦。

异常类的继承结构

从之前的三个异常:ArithmeticException  NumberFormatException  ArrayIndexOutOfBoundsException 。

在整个异常结构中有两个最常用的类:Exception  Error.这两个类都是继承子throwable的子类。

 

注意:

一般输出异常信息的时候可以直接使用System.out.println(e) ;

也可以使用Exception提供的一个方法:public void printStackTrace() ;

public class ExceptionDemo06{    public static void main(String args[]){        System.out.println("********** 计算开始 ***********") ;        int i = 0 ;        // 定义整型变量        int j = 0 ;            // 定义整型变量        try{            String str1 = args[0] ;        // 接收第一个参数            String str2 = args[1] ;        // 接收第二个参数            i = Integer.parseInt(str1) ;    // 将第一个参数由字符串变为整型            j = Integer.parseInt(str2) ;    // 将第二个参数由字符串变为整型            int temp = i / j ;    // 此处产生了异常            System.out.println("两个数字相除的结果:" + temp) ;            System.out.println("----------------------------") ;        }catch(ArithmeticException e){    // 捕获算术异常            // System.out.println("算术异常:" + e) ;            e.printStackTrace() ;        }catch(NumberFormatException e){    // 捕获数字转换异常            System.out.println("数字转换异常:" + e);        }catch(ArrayIndexOutOfBoundsException e){    // 捕获数组越界异常            System.out.println("数组越界异常:" + e) ;        }catch(Exception e){            System.out.println("其他异常:" + e) ;        }        System.out.println("********** 计算结束 ***********") ;    }};

异常处理机制

异常的处理步骤一般如下:

之前讲解过面向对象的多态性:子类的实例化对象可以直接使用父类的对象进行接收。

那么异常处理中也可以使用这种概念。因为try产生的是一个实例化对象。如果有其他不知道的异常的话,可以最后使用Exception进行捕获。

package methoud;public class ThisDemo06{    public static void main(String args[]){        System.out.println("********** 计算开始 ***********") ;        int i = 0 ;        // 定义整型变量        int j = 0 ;            // 定义整型变量        try{            String str1 = args[0] ;        // 接收第一个参数            String str2 = args[1] ;        // 接收第二个参数            i = Integer.parseInt(str1) ;    // 将第一个参数由字符串变为整型            j = Integer.parseInt(str2) ;    // 将第二个参数由字符串变为整型            int temp = i / j ;    // 此处产生了异常            System.out.println("两个数字相除的结果:" + temp) ;            System.out.println("----------------------------") ;        }catch(ArithmeticException e){    // 捕获算术异常            // System.out.println("算术异常:" + e) ;            e.printStackTrace() ;        }catch(NumberFormatException e){    // 捕获数字转换异常            System.out.println("数字转换异常:" + e);        }catch(ArrayIndexOutOfBoundsException e){    // 捕获数组越界异常            System.out.println("数组越界异常:" + e) ;        }catch(Exception e){            System.out.println("其他异常:" + e) ;        }        System.out.println("********** 计算结束 ***********") ;    }};

注意:捕获更粗的异常要放在捕获更细的异常前面。

因为如果放在前面会导致更细的异常捕获不到。例如下面:

package methoud;public class ThisDemo06{    public static void main(String args[]){        System.out.println("********** 计算开始 ***********") ;        int i = 0 ;        // 定义整型变量        int j = 0 ;            // 定义整型变量        try{            String str1 = args[0] ;        // 接收第一个参数            String str2 = args[1] ;        // 接收第二个参数            i = Integer.parseInt(str1) ;    // 将第一个参数由字符串变为整型            j = Integer.parseInt(str2) ;    // 将第二个参数由字符串变为整型            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) ;            e.printStackTrace() ;        }        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 methoud.ThisDemo06.main(ThisDemo06.java:18)

既然所有Exception对象都可以使用Exception接收(发生向上转型),那么直接使用Exception不是更方便吗?

package methoud;public class ThisDemo06{    public static void main(String args[]){        System.out.println("********** 计算开始 ***********") ;        int i = 0 ;        // 定义整型变量        int j = 0 ;            // 定义整型变量        try{            String str1 = args[0] ;        // 接收第一个参数            String str2 = args[1] ;        // 接收第二个参数            i = Integer.parseInt(str1) ;    // 将第一个参数由字符串变为整型            j = Integer.parseInt(str2) ;    // 将第二个参数由字符串变为整型            int temp = i / j ;    // 此处产生了异常            System.out.println("两个数字相除的结果:" + temp) ;            System.out.println("----------------------------") ;        }catch(Exception e){            System.out.println("其他异常:" + e) ;        }        System.out.println("********** 计算结束 ***********") ;    }}; 运行结果:

********** 计算开始 ***********

其他异常:java.lang.ArrayIndexOutOfBoundsException: 0
********** 计算结束 ***********

当所有的异常处理方式一致的时候就可以使用上诉方式。直接Exception进行捕获。当然开发中不建议,最好分别捕获。

问题:

既然Exception可以,那么直接Throwable可以吗?

首先这种做法是可以的,但开发人员一般不会这么做,因为程序中,try永远之后抛出Exception错误,而Throwable还有Error。

总结

1)异常出现后,如果没有合理的处理的话,则会让整个程序中断执行。

2)每当异常产生,会在程序中产生一个异常化的实例化对象,之后使用此对象与catch中的异常类型相互匹配,

如果匹配成功,则执行catch语句中内容,如果匹配不成功,向下继续匹配。如果都无法匹配,程序会中断执行。

转载于:https://www.cnblogs.com/alsf/p/5582051.html

你可能感兴趣的文章
【NOIP 模拟赛】Evensgn 剪树枝 树形dp
查看>>
java学习笔记④MySql数据库--01/02 database table 数据的增删改
查看>>
两台电脑如何实现共享文件
查看>>
组合模式Composite
查看>>
程序员最想得到的十大证件,你最想得到哪个?
查看>>
我的第一篇CBBLOGS博客
查看>>
【MyBean调试笔记】接口的使用和清理
查看>>
07 js自定义函数
查看>>
jQueru中数据交换格式XML和JSON对比
查看>>
form表单序列化后的数据转json对象
查看>>
[PYTHON]一个简单的单元測试框架
查看>>
iOS开发网络篇—XML数据的解析
查看>>
[BZOJ4303]数列
查看>>
一般处理程序在VS2012中打开问题
查看>>
C语言中的++和--
查看>>
thinkphp3.2.3入口文件详解
查看>>
POJ 1141 Brackets Sequence
查看>>
Ubuntu 18.04 root 使用ssh密钥远程登陆
查看>>
Servlet和JSP的异同。
查看>>
虚拟机centOs Linux与Windows之间的文件传输
查看>>