Java的异常处理

目录
- 异常的概念
-
异常的体系
-
异常的处理
-
基本语法
-
异常链条
-
自定义异常

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

  • 异常发生的原因有很多,通常包含以下几大类:

    1. 用户输入了非法数据。
    2. 要打开的文件不存在。
    3. 网络通信时连接中断,或者JVM内存溢出。
  • 异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的。

  • 三种类型的异常:

    • 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。
    • 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
    • 错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。
异常的体系
  • Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。

  • 在 API中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception。

  • 如下是异常树
    在这里插入图片描述

  • 所有异常类型都是内置类Throwable的子类,因而Throwable在异常类的层次结构的顶层。

  • Throwable分成了两个不同的分支,一个分支是Error,它表示不希望被程序捕获或者是程序无法处理的错误。另一个分支是Exception,它表示用户程序可能捕捉的异常情况或者说是程序可以处理的异常。其中异常类Exception又分为运行时异常(RuntimeException)和非运行时异常。

  • Java异常又可以分为不受检查异常(Unchecked Exception)和检查异常(Checked Exception)。

  • ​ |- Error:JVM、硬件、执行逻辑错误、不能手动处理。

  • |- Exception 程序在运行和配置中产生的问题,可处理

Exception又分为 检查异常和不受检查异常

  • 除了RuntimeException及其子类以外,其他的Exception类及其子类都属于检查异常,当程序中可能出现这类异常,要么使用try-catch语句进行捕获,要么用throws子句抛出,否则编译无法通过。
  • 不受检查异常为编译器不要求强制处理的异常,检查异常则是编译器要求必须处置的异常。
异常的处理
  • Java的异常处理本质上是抛出异常和捕获异常。
  • 抛出异常:就是从当前环境中跳出,并把问题提交给上一级环境,这就是抛出异常时所发生的事情。
public class TestExceptionPlus {
	public static void main(String[] args) {
		try {
			System.out.println("main1");
			ma();
			System.out.println("main2");
		}catch(Exception e) {
			System.out.println("In Catch");
		}
	}
	public static void ma() {
		System.out.println("ma1");
		throw new NullPointerException(); // 这里就是异常地抛出
	}
}
  • 捕获异常:在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器(exception handler)。潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合。当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适的异常处理器。运行时系统从发生异常的方法开始,依次回查调用栈中的方法,直至找到含有合适异常处理器的方法并执行。当运行时系统遍历调用栈而未找到合适的异常处理器,则运行时系统终止。同时,意味着Java程序的终止。
  • Java异常处理涉及到五个关键字
      • try – 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。
      • catch – 用于捕获异常。catch用来捕获try语句块中发生的异常。
      • finally – finally语句块总是会被执行。它主要用于回收在try块里打开的物力资源(如数据库连接、网络连接和磁盘文件)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
      • throw – 用于抛出异常。
      • throws – 用在方法签名中,用于声明该方法可能抛出的异常。
基本语法
  1. try-catch
try{
    
}catch(Exception e){
    
}
  1. try-catch-catch
try{
    
}catch(Exception e){
    
}catch(Exception e){
   
}
  1. try-catch-finally
try{
    
}catch(Exception e){
    
}finally{

}
  1. try-catch-catch-…-finally
try{
    
}catch(Exception e){
    
}catch(Exception e){

}finally{

}
  1. try-finally
try{

}finally{

}
  1. throw
    用throw语句抛出明确的异常。Throw的语法形式如下:
throw ThrowableInstance;
  1. throws
  • 如果一个方法可以导致一个异常但不处理它,它必须指定这种行为以使方法的调用者可以保护它们自己而不发生异常。要做到这点,我们可以在方法声明中包含一个throws子句。一个throws子句列举了一个方法可能引发的所有异常类型。这对于除了Error或RuntimeException及它们子类以外类型的所有异常是必要的。一个方法可以引发的所有其他类型的异常必须在throws子句中声明,否则会导致编译错误。
public static void ma() throws IOException{}
异常链条
  • 异常链顾名思义就是将异常发生的原因一个传一个串起来,即把底层的异常信息传给上层,这样逐层抛出。 Java API文档中给出了一个简单的模型:
try {   
    lowLevelOp();   
} catch (LowLevelException le) {   
    throw (HighLevelException) new HighLevelException().initCause(le);   
}
  • 当程序捕获到了一个底层异常,在处理部分选择了继续抛出一个更高级别的新异常给此方法的调用者。 这样异常的原因就会逐层传递。这样,位于高层的异常递归调用getCause()方法,就可以遍历各层的异常原因。 这就是Java异常链的原理。
自定义异常

使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可。

在程序中使用自定义异常类,大体可分为以下几个步骤:

  • 创建自定义异常类。
  • 在方法中通过throw关键字抛出异常对象。
  • 如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否 则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。
  • 在出现异常方法的调用者中捕获并处理异常。

public class TestThrowException {
	public static void main(String[] args) {
		Student stu = new Student();
		stu.setAge(10);
	}
}

class Student{
	private int age;
	public int getAge() {
		return this.age;
	}
	public void setAge(int age) throws AgeException{
		if(age > 0 && age < 125) {
			this.age = age;
		} else {
			throw new AgeException("年龄扯犊子");
		}
	}
}
class AgeException extends RuntimeException{
	public AgeException(String name) {
		super(name);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值