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

前言

本篇文章笔者准备重点介绍异常的产生原理,异常处理的基本格式,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,所以验证结果就出现了问题。

总结

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值