Java基础知识——异常

异常简介

定义:Java异常是Java提供的一种识别及响应错误的一致性机制。

作用:Java异常机制可以使程序中异常处理代码和正常业务代码分离,保证程序代码更加优雅,并提高程序健壮性。在有效使用异常的情况下,异常能清晰的回答what, where, why这3个问题:异常类型回答了“什么”被抛出,异常堆栈跟踪回答了“在哪“抛出,异常信息回答了“为什么“会抛出。

异常分类

java.lang.Throwable

  |– Error错误:JVM内部的严重问题。无法恢复。程序人员不用处理。 

  |–Exception异常:普通的问题。通过合理的处理,程序还可以回到正常执行流程。要求编程人员要进行处理。 

  |–RuntimeException:也叫非受检异常(unchecked exception).这类异常是编程人员的逻辑问题。应该承担责任。Java编译器不进行强制要求处理。 也就是说,这类异常再程序中,可以进行处理,也可以不处理。 

  |–非RuntimeException:也叫受检异常(checked exception).这类异常是由一些外部的偶然因素所引起的。Java编译器强制要求处理。也就是说,程序必须进行对这类异常进行处理。
复制代码

异常处理机制

  • 当程序再运行过程中出现了异常,JVM自动创建一个该类型的异常对象。同时把这个异常对象交给运行时系统。(抛出异常)
  • 运行时系统接受到一个异常对象时,它会再产生异常的代码附近查找相应的处理方式。
  • 异常的处理方式有两种:
    1. 捕获并处理:在异常的代码附近显示用try/catch进行处理(不合理),运行时系统捕获后会查询相应的catch处理块,再catch处理块中对该异常进行处理。
    2. 查看发生异常的方法是否有向上声明异常,有向上声明,向上级查询处理语句,如果没有向上声明,JVM中断程序的运行并处理。用throws向外声明(合理的处理方法)

Java异常机制用到的几个关键字:try、catch、finally、throw、throws。

try -- 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。

catch -- 用于捕获异常。catch用来捕获try语句块中发生的异常。

finally -- finally语句块总是会被执行。它主要用于回收在try块里打开的物力资源(如数据库连接、网络连接和磁盘文件)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。

throw -- 用于抛出异常。

throws -- 用在方法签名中,用于声明该方法可能抛出的异常。

异常处理方式:

1、显示用try/catch进行处理

try{
    //可能会出现异常的代码段;
}catch(异常类型1 变量名){ //处理制定类型的异常
    //对该类型异常的处理代码段;
}catch(异常类型2 变量名){
}finally{
    //无论是否发生异常都要执行的代码段;
    //经常用来清理资源
}
复制代码

2、向上声明:用throws关键字,向外声明本方法可能会抛出的异常列表。

...方法名(参数列表) throws 异常类型1,异常类型2
复制代码

3、手动抛出一个异常:当程序逻辑不符合期望时,要中止后面代码的执行时。在方法的代码段中,可以使用throw关键字手动抛出一个异常。 **注意:**如果手动抛出的是受检异常,那么本方法必须进行处理(应该采用向上声明这个异常);如果手动抛出的是非受检异常,那么可以进行处理,也可以不处理。

异常继承结构

基类为***Throwable***,Error和Exception继承Throwable,RuntimeException和IOException、SQLException等继承Exception。

java异常类结构

检查异常(checked exception)和未检查异常(unchecked exception)

ErrorRuntimeException及其子类成为未检查异常(unchecked),其它异常成为已检查异常(checked)。

检查异常:编译器要求必须处置的异常。

​ 处理方式: ​ 1、通过throws exception继续抛出,消极的方法,一直可以抛到java虚拟机来处理。 ​ 2、用try...catch捕获。 ​ 注意:检查异常必须处理,捕获或者抛出。

非检查异常:编译器不要求强制处置的异常。这类异常常常只能在运行时才能检查出来,比如空指针,堆溢出等。

​ 处理方式: ​ 1、捕获 ​ 2、继续抛出 ​ 3、不处理

运行时异常和非运行时异常

运行时异常RuntimeException类及其子类,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是非检查异常,程序中可以选择捕获处理,也可以不处理。一般由程序逻辑错误引起。

处理RuntimeException的原则是:如果出现RuntimeException,那么一定是程序员的错误。

运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,如果有异常产生,则异常将由JVM进行处理,编译也会通过。

对于RuntimeException的子类最好也使用异常处理机制。虽然RuntimeException的异常可以不使用try...catch进行处理,但是如果一旦发生异常,则肯定会导致程序中断执行,所以,为了保证程序再出错后依然可以执行,在开发代码时最好使用try...catch的异常处理机制进行处理。

非运行时异常:非RuntimeException类及其子类,如IOException、SQLException等以及用户自定义的Exception异常等,从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。

RuntimeException和Exception

RuntimeException:运行时异常,在项目运行之后出错则直接中止运行,异常由JVM虚拟机处理。

Exception,:非运行时异常,在项目运行之前必须处理掉。一般由程序员try catch 掉。

自定义异常类需要继承Exception或RunExcption。

注意:覆盖父类某方法的子类方法不能抛出比父类方法更多的异常,所以,有时设计父类的方法时会声明抛出异常,但实际的实现方法的代码却并不抛出异常,这样做的目的就是为了方便子类方法覆盖父类方法时可以抛出异常。

常见的RuntimeException

RuntimeException是开发中最容易遇到的,下面列举一下常见的RuntimeException:

1、NullPointerException:空指针异常;

2、NumberFormatException:继承IllegalArgumentException,字符串转换为数字时出现。比如int i= Integer.parseInt("ab3");

3、ArrayIndexOutOfBoundsException:数组越界。比如 int[] a=new int[3]; int b=a[3];

4、StringIndexOutOfBoundsException:字符串越界。比如 String s="hello"; char c=s.chatAt(6);

5、ClassCastException:类型转换错误。比如 Object obj=new Object(); String s=(String)obj;

6、ArithmeticException:算术错误,典型的就是0作为除数的时候。

7、IllegalArgumentException:非法参数,在把字符串转换成数字的时候经常出现的一个异常,我们可以在自己的程序中好好利用这个异常。

参考文章链接:

www.cnblogs.com/skywang1234…

blog.csdn.net/lx520aa/art…

blog.csdn.net/yy_wg/artic…

blog.csdn.net/wqc19920906…

猜你喜欢

转载自juejin.im/post/5c626269f265da2dc37b0c29
今日推荐