JAVA异常详解

参考链接:https://blog.csdn.net/michaelgo/article/details/82790253
参考链接:https://blog.csdn.net/weixin_39220472/article/details/81056647
参考链接:https://blog.csdn.net/xsj_blog/article/details/83030450

JAVA异常分类

异常分类图:
异常分类图

  • Throwable:所有异常的父类(Error与Exception),所有的异常都是其子类。它可以分为检查异常与非检查的异常。
    检查异常:就是编译器要求你必须处置的异常。不知道你编程的时候有没有遇到过,你写的某段代码,编译器要求你必须要对这段代码try…catch,或者throws exception,如果你遇见过,没错,这就是检查异常,也就是说,你代码还没运行呢,编译器就会检查你的代码,会不会出现异常,要求你对可能出现的异常必须做出相应的处理。
    那么需要如何处理检查异常呢?继续抛出,一直可以抛到java虚拟机来处理,就是通过throws exception抛出:或者用try…catch捕获。
    除了RuntimeException与其子类,以及错误(Error),其他的都是检查异常(绝对的大家族)
    非检查异常:编译器不要求强制处置的异常。事实上不能对其进行处置(不知道会发生哪些异常)
    对于非检查异常的处理,一般可以采取三种方法:捕获、继续抛出、不处理(绝大多数)
    RuntimeException与其子类(空指针异常,栈溢出异常等等),以及错误(Error)。
  • Error:是错误,程序不可处理。对于所有的编译时期的错误以及系统错误都是通过Error抛出的。这些错误表示故障发生于虚拟机自身、或者发生在虚拟机试图执行应用时,如:Java虚拟机运行错误(Virtual MachineError),类定义错误(NoClassDefFoundError)等。这些错误是不可查的,因为它们在应用程序的控制和处理能力之 外,而且绝大多数是程序运行时不允许出现的状况。对于设计合理的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。在 Java中,错误通过Error的子类描述。
  • Exception:是另外一个非常重要的异常子类,程序可以处理。它规定的异常是程序本身可以处理的异常。其可以分为运行时异常和非运行时异常。
    运行时异常:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是非检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
    运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
    非运行时异常:是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常

JAVA的异常处理流程

异常的处理流程图:

异常流程处理
过程描述:

  1. 当产生异常时,JVM会自动根据异常的类型实例化一个制定的异常类对象。
  2. 程序判断当前代码中是否有程序异常处理,如没有则由JVM自动处理,输出异常信息,而后中断程序。
  3. 若程序中有异常对象,则try会捕获该异常类实例化对象.
  4. 捕获到的异常类的实例化对象,与catch中的异常对象依次进行匹配。
  5. 若catch配皮到了异常,则进行相应的处理,若没有任何一个catch匹配,最后直接进入到finally
  6. 若异常未被处理,则交由JVM自动处理,抛出异常信息,而后程序中断

注: 当一个try语句进行进行多个异常捕获时(既有多个异常,有多个catch),则捕获范围大的异常必须放在捕获范围小的异常后面。否则会出现语法错误。

JAVA的异常处理

  1. 用try—catch—finally进行捕获
try {  // 进行异常的捕获,若无异常,则全部运行,若有异常,则会中断运行,及逆行catch捕获
			
		}catch(Exception e) {
			e.printStackTrace();  // 返回此异常的相关信息(异常发生的行数,异常名称......),范围大的catch要在范围小的之后
		}finally{ // 无论是否发生异常,此代码都会运行
			
		}
  1. 用throws抛出异常(在具体位置不处理,直接抛出,通过throws/throw到上层再进行处理)
    如果一个方法没有捕获到一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。也可以使用 throw 关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。
public class Test{
	public static void main(String args[]) throws IOException {  // 对input抛出的异常进行捕获,否则进行try--catch捕获
		IO io=new IO();
		io.input();
		
	}
}
class IO{
	public void input() throws IOException {  // 进行异常的抛出,抛出至调用此函数的函数进行处理,若在此函数内部直接把异常及逆行try--catch捕获,则巧用此函数的函数无需再进行捕获或抛出
		InputStreamReader f=new FileReader("a.txt");
		f.close();
	}
}

throw与throws的区别:

  • throws出现在方法函数头;而throw出现在函数体。
  • throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常对象。
  • 两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。

注:

  • 在写程序时,对可能会出现异常的部分通常要用try{…}catch{…}去捕捉它并对它进行处理;
  • 用try{…}catch{…}捕捉了异常之后一定要对在catch{…}中对其进行处理,那怕是最简单的一句输出语句,或栈输入e.printStackTrace();
  • 如果是捕捉IO输入输出流中的异常,一定要在try{…}catch{…}后加finally{…}把输入输出流关闭;
  • 如果在函数体内用throw抛出了某种异常,最好要在函数名中加throws抛异常声明,然后交给调用它的上层函数进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值