Java核心编程之异常的捕获及处理

来源:互联网 发布:神经网络算法能做什么 编辑:程序博客网 时间:2024/06/05 09:51

前言

本篇文章笔者准备重点介绍异常的产生原理,异常处理的基本格式,throw和throws关键字的作用,自定义异常,以及Exception与RuntimeException的区别,断言的作用等等

异常的基本概念

异常是导致程序中断运行的一种指令流,如果不对异常进行正确的处理,则可能导致程序的中断执行,造成不必要的损失,所以在程序的设计中必须要考虑各种异常的发生,并正确做好相应的处理,这样才能保证程序的正常运行。在Java中一切异常都秉着面向对象的设计思想,所有的异常都以类和对象的形式存在,除了Java中已经提供的各种异常类外,用户也可以根据需要定义自己的异常类。

为什么需要异常处理

在没有异常处理的语言中如果要回避异常,就必须使用大量的判断语句,配合所想到的错误状况来捕捉程序中所有可能发生的错误。但为了捕捉这些错误,编写出来的程序代码经常有大量的判断语句,又是这样也未必能捕捉到所有的错误,而且这样做势必导致程序的运行效率的降低。

Java的异常处理机制恰好改进这一点。它具有易于使用,可自行定义异常类,处理抛出的异常同时又不会降低程序运行的速度等优点。因在Java程序设计时,应充分利用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.print("两个数字相除结果:" +temp);System.out.print(******计算结果*******);}}

程序运行结果:

计算开始
Exception in thread”main”java.lang.ArithmeticException:/by zero at ExceptionDemo01.main(ExceptionDemo01.java:6 )

在以上程序中,因为被除数为0,所以程序中出现异常,从运行结果可以发现,如果不对异常进行处理,则一旦出现异常后,程序立刻退出,所以后面的两条语句并没有打印输出。此程序的执行流程如图所示
这里写图片描述

解决方案

在程序中进行异常处理

这里写图片描述

范例

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
计算结束

这里写图片描述

从图中可以清楚的看到,所有异常都在catch中处理了,catch处理完毕之后,程序正常结束。实际上在异常处理的最后有一个finally关键字,可以使用它作为异常的统一接口。

验证finally关键字

public class ExceptionDemo03{public static void main(String[] args){System.out.print("******计算开始******");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:/byzero
不管是否出现异常,都执行此代码
计算结束

通常程序开发中不会只有一个异常,肯定同时存在多个异常,此时就需要了解异常类的继承结构

这里写图片描述

  • Exception:一般表示的是程序中出现的问题,可以直接使用try….catch处理。
  • Error:一般指的是JVM错误,程序中无法处理。
  • 一般情况下,开发者习惯于将Exception和Error统称为异常,而算术异常,数字格式异常等都属于Exception的子类。

Java异常信息的输出方式

  • System.out.println(异常对象)
  • e.printStackTrace()

Java的异常处理机制

在整个Java的异常处理中,实际上也是按照面向对象的方式进行处理,处理的步骤如下:
(1) 一旦产生异常,则首先会产生一个异常类的实例化对象。
(2)在try语句中对此异常类进行捕捉
(3)产生的异常对象与catch语句的各个异常类型进行匹配,如果匹配成功,则执行catch语句中的代码。
这里写图片描述

从之前学习过的对象多态性可以清楚的知道,所有的子类实例可以全部使用父类类型接收,那么就可以利用向上转型的概念,让所有的异常对象都使用Exception接收。

范例

public class ExceptionDemo{public static void main(String[] args){System.out.println(********计算开始*******);int i=0;int j=0;try{String str1=args[0];String str2=arg[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(*******计算结束*******); }} 

以上代码直接使用Exception进行异常处理,所以任何的异常都可以非常方便地进行处理。

throws与throw关键字

throws关键字

在定义一个方法时可以使用throws关键字声明,使用throws声明的方法表示此方法不处理异常,而交给方法的调用处进行处理。

范例:处理异常

class Math{public int div(int i,int j)throws Exception{ //本方法不处理异常int temp=i/j;return temp;}}public class ThrowsDemo01{public static void main(String[] args){Math m=new Math();try{    //因为有throws,不管是否有异常,都必须处理        System.out.println("除法操作:"+m.div(10,2));}catch(Exception e){e.printStackTrace();}}}

程序运行结果:

除法操作:5


以上代码中,不管是否有问题,都要使用try…catch块进行异常的捕获与处理。既然throws是在方法处定义的,那么在主方法中也可以使用throws关键字,但是主方法为程序的起点,所以此时主方法再向上抛异常,则只能将异常抛给JVM进行处理。这就好比一个公司,部门事情处理不了,要上报给经理,经理再解决不了要上报给董事长,到董事长了,也就到头了,那么Java的头就是JVM。

范例:主方法处使用throws关键字

class Math{public int div(int i, int j)throws Exception{int temp=i/j;return temp;}}public class ThrowsDemo{//本方法中所有的异常都可以不使用try....catch处理的public static void main(String[] args){Math m=new Math();System.out.println("除法操作:"+m.div(102));}}

以上代码在主方法处使用了throws关键字,所以在程序主方法中就可以不再使用try…catch语句进行异常的捕获及处理。

提醒

主方法为一切的起点,一切的操作也都是由主方法开始的。所以如果在主方法中使用throws,则程序出现问题后肯定交由JVM进行处理,将导致程序中断。

throw关键字

与throws关键字不同的是,可以直接使用throw关键字人为地抛出一个异常,抛出时直接抛出异常类的实例化对象即可。

范例:抛出异常

public class ThrowDemo01{public static void main(String[] args){try{throw new Exception("自己抛出的异常!");//抛出异常的实例化对象}catch(Exception e){System.out.println(e);}}}

程序运行结果:

java.lang.Exception:自己抛出的异常!

throw与throws的综合运用

class Math{public int div(int i, int j)throws Exception{  //方法不可以处理异常System.out.println("******计算开始*******");int temp=0;try{temp=i/j;}cath(Exception e){throw e  //把异常交给被调用处}finally{ System.out.println("******计算结束*****");}return temp;}}public class ThrowDemo{public static void main(String[] args){Math m = new Math();try{System.out.println("除法操作:"+m.div(10,0));}catch(Exception e){System.out.println("异常产生:"+e);}}}

程序运行结果:

计算开始
计算结束
异常产生:java.lang.ArithmeticException:/by zero

Exception类与RuntimeException类的区别

这里写图片描述

自定义异常类

在Java中已经提供了大量的异常类,但是这些异常类有时也很难满足开发者的需要,所以用户可以根据自己的需要来定义自己的异常类。定义自己的异常类只需要继承Exception类即可

范例:

class MyException extends Exception{ //自定义异常类,继承Exception类public MyException(String msg){super(msg);}}public class DefaultException{public static void main(String[] args){try{    throw new MyException("自定义异常。");    }catch(Exception e){    System.out.println(e);    } }}    

程序运行结果:

MyException:自定义异常。

断言

在JDK1.4之后,Java中增加了断言的功能。断言就是肯定某一结果的返回值是正确的,如果最终此结果的返回值是错误的,则通过断言检查肯定会提示错误信息。

范例:

public class Test{public static void main(String[] args){int x[]={1,2,3}assert x.length==0;}}

以上程序中,数组x的长度是不可能为0的,所以,此处的断言结果是错误的,但此时运行程序并不会得到任何的结果,因为Java在设计assert关键字时考虑到系统的应用。
如果要想让断言起作用,可以使用一下参数运行参数
编译程序: javacTest.java
验证程序:java -ea Test

程序运行结果:

Exception in thread “main”java.lang.AssertionError at Test.main(Test.java:4)

以上出现的是断言错误,因为数组x的长度不可能是0,所以验证结果就出现了问题。

总结

以上就是笔者对异常的一点理解,有什么不足,请多多指教!

原创粉丝点击