java异常体系

来源:互联网 发布:ubuntu和redhat的区别 编辑:程序博客网 时间:2024/06/07 11:28

一、基本概念

1.异常是程序运行过程中出现的错误。Java语言的异常处理框架, 是Java语言健壮性的一个重要体现

2.异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的

3.Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类

二、异常分类

这里写图片描述

1.Error——是程序无法处理的错误,比如OutOfMemoryError、ThreadDeath等。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止

2.Exception——是程序本身可以处理的异常

1)运行时异常(非检查异常)
  • (1)运行时异常都是RuntimeException类及其子类异常
  • (2)程序中可以选择捕获处理,也可以不处理
  • (3)这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生
  • (4)常见运行时异常:
    1)ArithmeticException 当出现异常的运算条件时,抛出此异常。例如,一个整数”除以零”时,抛出此类的一个实例
    2) ArrayIndexOutOfBoundsException 用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引
    3) ClassCastException 当试图将对象强制转换为不是实例的子类时,抛出该异常
    4) IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参数
    5) IndexOutOfBoundsException 指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出
    6) NullPointerException 当应用程序试图在需要对象的地方使用 null 时,抛出该异常
    7) UnsupportedOperationException 当不支持请求的操作时,抛出该异常
2)非运行时异常(检查异常)
  • (1)非运行时异常是RuntimeException以外的异常,类型上都属于Exception类及其子类
  • (2)从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过
  • (3)如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常
  • (4)常见检查性异常:(不能编译通过)
    1)ClassNotFoundException 应用程序试图加载类时,找不到相应的类,抛出该异常
    2)IllegalAccessException 拒绝访问一个类的时候,抛出该异常
    3)InterruptedException 一个线程被另一个线程中断,抛出该异常
    4)IOException
    5) SQLException
注意:异常和错误的区别:异常能被程序本身可以处理,错误是无法处理

三、异常处理机制——抛出异常,捕捉异常

1.抛出异常

  • 1)当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统,异常对象中包含了异常类型和异常出现时的程序状态等异常信息。
    运行时系统负责寻找处置异常的代码并执行。

2.捕获异常

  • 1)在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器(exception handler)
  • 2)运行时系统从发生异常的方法开始,依次回查调用栈中的方法,直至找到含有合适异常处理器的方法并执行。当运行时系统遍历调用栈而未
    找到合适的异常处理器,则运行时系统终止。
  • 3)对于运行时异常、错误或可查异常,Java技术所要求的异常处理方式有所不同

    (1)由于运行时异常的不可查性,为了更合理、更容易地实现应用程序,Java规定,运行时异常将由Java运行时系统自动抛出,允许
    应用程序忽略运行时异常
    (2)对于方法运行中可能出现的Error,当运行方法不欲捕捉时,Java允许该方法不做任何抛出声明。因为,大多数Error异常属于永
    远不能被允许发生的状况,也属于合理的应用程序不该捕捉的异常
    (3)对于所有的可查异常,Java规定:一个方法必须捕捉,或者声明抛出方法之外。也就是说,当一个方法选择不捕捉可查异常时,
    它必须声明将抛出异常

  • 4)一个方法所能捕捉的异常,一定是Java代码在某处所抛出的异常。简单地说,异常总是先被抛出,后被捕捉的

  • 5)任何Java代码都可以抛出异常,如:自己编写的代码、来自Java开发环境包中代码,或者Java运行时系统。无论是谁,都可以通过Java的
    throw语句抛出异常。
  • 6)从方法中抛出的任何异常都必须使用throws子句
  • 7)捕捉异常通过try-catch语句或者try-catch-finally语句实现

总体来说,Java规定:对于可查异常必须捕捉、或者声明抛出。允许忽略不可查的RuntimeException和Error。

四、异常的五个关键字

1.try…catch…finally

1) 格式
            try{                     //(尝试运行的)程序代码               }catch(异常类型 异常的变量名){                     // 异常处理代码               }finally{                     // 异常发生,方法返回之前,总是要执行的代码               }
2)try语句块,表示要尝试运行代码,try语句块中代码受异常监控,其中代码发生异常时,会抛出异常对象
3)catch语句块会捕获try代码块中发生的异常,并和自己的异常类型匹配,并在其代码块中做异常处理.catch语句可以有多个,用来匹配多个中的一个异常,一旦匹配上后,就不再尝试匹配别的catch块了
4)finally语句块
  • (1)这个语句块总是会在方法返回前执行, 而不管是否try语句块是否发生异常
  • (2)不管有木有出现异常,finally块中代码都会执行;
  • (3)当try和catch中有return时,finally仍然会执行;
  • (4)finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
  • (5)finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
5)应当要注意的问题:

(1)三个语句块均不能单独使用,三者可以组成 try…catch…finally、try…catch、try…finally三种结构,catch语句可以有
一个或多个,finally语句最多一个
(2)try、catch、finally三个代码块中变量的作用域为代码块内部,分别独立而不能相互访问。如果要在三个块中都可以访问,则需
要将变量定义到这些块的外面
(3)多个catch块时候,只会匹配其中一个异常类并执行catch块代码,而不会再执行别的catch块,并且匹配catch语句的顺序是由上
到下

2.throw

1)throw关键字是用于方法体内部,用来抛出一个Throwable类型的异常。
2)如果抛出了检查异常, 则还应该在方法头部声明方法可能抛出的异常类型。
3)如果所有方法都层层上抛获取的异常,最终JVM会进行处理,处理也很简单,就是打印异常消息和堆栈信息

3.throws

1) throws关键字用于方法体外部的方法声明部分,用来声明方法可能会抛出某些异常。
2) 仅当抛出了检查异常,该方法的调用者才必须处理或者重新抛出该异常。
3) 当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵吞枣一般在catch块中打印一下堆栈信息做个勉强处理

四、异常处理的一般原则

1.能处理就早处理,抛出不去还不能处理的就想法消化掉或者转换为RuntimeException处理。因为对于一个应用系统来说,抛出大量异常是有问题的,应该从程序开发角度尽可能的控制异常发生的可能。
2.对于检查异常,如果不能行之有效的处理,还不如转换为RuntimeException抛出。这样也让上层的代码有选择的余地,可处理也可不处理。
3.对于一个应用系统来说,应该有自己的一套异常处理框架,这样当异常发生时,也能得到统一的处理风格,将优雅的异常信息反馈给用户。

五、自定义异常(写一个类继承Exception或者RuntimeException)

参考网址

1.深入理解java异常处理机制
2.Java异常体系结构

注:文章是经过参考其他的文章然后自己整理出来的,有可能是小部分参考,也有可能是大部分参考,但绝对不是直接转载,觉得侵权了我会删,我只是把这个用于自己的笔记,顺便整理下知识的同时,能帮到一部分人。
ps : 有错误的还望各位大佬指正,小弟不胜感激

原创粉丝点击