异常及其处理

目录

异常概念

异常体系结构

异常之间的区别与联系

Error

Exception

检查异常和不受检查异常

JAVA异常处理机制

抛出异常

捕获异常

异常处理五个关键字

处理异常

try-catch

throw

throws

final

自定义异常


 

 

 

异常概念

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAaXNfa2Q=,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAaXNfa2Q=,size_20,color_FFFFFF,t_70,g_se,x_16

 

要理解Java异常处理是如何工作的,你需要掌握以下三种类型的异常:
  • 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
  • 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
  • 错误:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。

异常体系结构

Java把异常当作对象来处理,并定义一个基类java.long.Throwable作为所有异常的超类
watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAaXNfa2Q=,size_20,color_FFFFFF,t_70,g_se,x_16

 

从图中可以看出所有异常类型都是内置类 Throwable 的子类,因而 Throwable 在异常类的层次结
构的顶层。
接下来 Throwable 分成了两个不同的分支, 一个分支是 Error ,它表示不希望被程序捕获或者是程序 无法处理的错误另一个分支是 Exception ,它表示用户程序可能捕捉的异常情况或者说是程序可以处 理的异常
其中异常类 Exception 又分为运行时异常( RuntimeException )和非运行时异常。Java异常又可以
分为不受检查异常( Unchecked Exception )和检查异常( Checked Exception )。

异常之间的区别与联系

Error

Error 类对象由 Java 虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。

Exception

在 Exception 分支中有一个重要的子类 RuntimeException(运行时异常),该类型的异常自动
为你所编写的程序定义 ArrayIndexOutOfBoundsException(数组下标越界)、NullPointerException(空指针异常)ArithmeticException(算术异常)、MissingResourceException(丢失资源)、ClassNotFoundException(找不到类)等异常,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。

检查异常和不受检查异常

检查异常:在正确的程序运行过程中,很容易出现的、情理可容的异常状况,在一定程度上这种异常的发生是可以预测的,并且一旦发生该种异常,就必须采取某种方式进行处理。
解析: 除了 RuntimeException 及其子类以外,其他的 Exception 类及其子类都属于检查异常,当程序中可能出现这类异常, 要么使用 try-catch 语句进行捕获,要么用 throws 子句抛出,否则编译无法通过。
不受检查异常:包 RuntimeException 及其子类和 Error

JAVA异常处理机制

本质:抛出异常和捕获异常

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAaXNfa2Q=,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAaXNfa2Q=,size_20,color_FFFFFF,t_70,g_se,x_16 watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAaXNfa2Q=,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAaXNfa2Q=,size_20,color_FFFFFF,t_70,g_se,x_16

抛出异常

首先,是像创建普通的java对象一样将使用 new 在堆上创建一个异常对象;然后,当前的执行路径(已经无法继续下去了)被终止,并且从当前环境中弹出对异常对象的引用。此时,异常处理机制接管程序,并开始寻找一个恰当的地方继续执行程序,这个恰当的地方就是异常处理程序或者异常处理器,它的任务是将程序从错误状态中恢复,以使程序要么换一种方式运行,要么继续运行下去。
 
if(stu == null){
 throw new NullPointerException();
 }
假使我们创建了一个学生对象Student的一个引用stu,在调用的时候可能还没有初始化。所以在使用这个对象引用调用其他方法之前,要先对它进行检查,可以创建一个代表错误信息的对象,并且将它从当前环境中抛出,这样就把错误信息传播到更大的环境中。

捕获异常

在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器(exception handler)。
潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合。
当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适的异常处理器。
运行时系统从发生异常的方法开始,依次回查调用栈中的方法,直至找到含有合适异常处理器的方法并执行。当运行时系统遍历调用栈而未找到合适的异常处理器,则运行时系统终止。同时,意味着Java程序的终止。

异常处理五个关键字

try 、 catch 、 finally 、 throw 、 throws
try -- 用于监听。
catch -- 用于捕获异常。
finally -- fifinally语句块总是会被执行。
只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
throw -- 用于抛出异常。
throws -- 用在方法签名中,用于声明该方法可能抛出的异常。

处理异常

try-catch

try{
//code that might generate exceptions
 }catch(Exception e){
 //the code of handling exception1
 }catch(Exception e){
 //the code of handling exception2
 }
try-catch 所描述的即是监控区域,关键词 try 后的一对大括号将一块可能发生异常的代码包起来,即为监控区域。
public class TestException {
 public static void main(String[] args) {
 int a = 1;
 int b = 0;
 try {
 // try监控区域
 if (b == 0) throw new ArithmeticException();
 // 通过throw语句抛出异常
 System.out.println("a/b的值是:" + a / b);
 System.out.println("this will not be printed!");
 }catch (ArithmeticException e) { 
// catch捕捉异常
 System.out.println("程序出现异常,变量b不能为0!");
 }
System.out.println("程序正常结束。"); } }


//输出 程序出现异常,变量b不能为0! 程序正常结束。
显示一个异常的描述, Throwable 重载了 toString() 方法(由 Object 定义),所以
它将返回一个包含异常描述的字符串。例如,将前面的 catch 块重写成:
public class TestException {
 public static void main(String[] args) {
 int a = 1;
 int b = 0;
 System.out.println("a/b的值是:" + a / b);
 System.out.println("this will not be printed!");
 }
 }

//结果: Exception in thread "main" java.lang.ArithmeticException: / by zero at TestException.main(TestException.java:7)
使用多重的catch语句:很多情况下,由单个的代码段可能引起多个异常。处理这种情况,我们需要定义两个或者更多的 catch 子句,每个子句捕获一种类型的异常,当异常被引发时,每个 catch 子句被依次检查,第一个匹配异常类型的子句执行,当一个 catch 子句执行以后,其他的子句将被旁路。
顺序问题:先小后大,即先子类后父类
 
嵌套try语句: try 语句可以被嵌套。也就是说,一个 try 语句可以在另一个 try 块的内部。每
次进入 try 语句,异常的前后关系都会被推入堆栈。如果一个内部的 try 语句不含特殊异常的
catch 处理程序,堆栈将弹出,下一个 try 语句的 catch 处理程序将检查是否与之匹配。这个
过程将继续直到一个 catch 语句被匹配成功,或者是直到所有的嵌套 try 语句被检查完毕。如果
没有 catch 语句匹配,Java运行时系统将处理这个异常。
class NestTry{
 public static void main(String[] args){
 try{
 int a = args.length;
 int b = 42 / a;
 System.out.println("a = "+ a);
     try{
        if(a == 1){
         a = a/(a-a);
       }if(a == 2){
         int c[] = {1};
          c[42] =99;
          }
      }catch(ArrayIndexOutOfBoundsException e){
 System.out.println("ArrayIndexOutOfBounds :"+e);
      }
 }catch(ArithmeticException e){
 System.out.println("Divide by 0"+ e);
 } 
}
}//分析运行:
 D:\java>java NestTry one a = 1
 Divide by 0java.lang.ArithmeticException: / by zero
 D:\java>java NestTry one two
 a = 2
 ArrayIndexOutOfBounds :java.lang.ArrayIndexOutOfBoundsException: 42

 

throw

throws

final

自定义异常

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值