JavaSE_强化篇_kuang
JavaSE:异常机制
异常,简单,但需要好好学
异常概念
异常指程序运行中出现的不期而至的各种状况,如:文件找不到、网络连接失败、非法参数等。
异常发生在程序运行期间,它影响了正常的程序执行流程。
要理解Java异常处理是如何工作的,你需要掌握一下三种类型的异常:
- **检查性异常:**最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
- **运行时异常:**运行时异常是可能被程序员避免的问题,与检查性异常相反,运行异常可以在编译时被忽略。
- **错误:**错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,他们在编译也检测不到的。
Java异常是一个描述在代码段中发生异常的对象,当发生异常情况时,一个代表该异常的对象被创建并且在导致该异常的方法中被抛出,而该方法可以选择自己处理异常或者传递该异常。
异常体系结构
Java把异常当做对象来处理,并定义一个基类java.lang.Throwable
作为所有异常的超类。
在Java API中已经定义了许多异常类,这些异常分为两大类,错误Error和异常Exception
Java异常层次结构图:
从图中可以看出所有异常类型都是内置类 throwable
的子类,因而throwable
在异常类的层次结构的顶层。
接下来throwable
分成了两个不同的分支,一个分支是Error,它表示不希望被程序捕获或者是程序无法处理的错误。另一个分支是Exception,它表示用户程序可能捕获的异常情况或者说是程序可以处理的异常
其中异常类Exception
又分为运行时异常(RuntimeException
)和非运行时异常。Java异常又可以分为不受检查异常(unchecked Exception
)和检查异常(checked Exception
)。
异常之间的区别与联系
1、Error
Error
类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。
Virtual MachineError
、OutofMemoryError
、NoClassDefFoundError
、LinkageError
、Error
2、Exception
Exception
RuntimeException
、ArrayIndexOutofBoundsException
、NullPointerException
、ArithmeticException
、MissingResourceException
、ClassNotFoundException
3、检查异常和不受检测异常
检查异常:在正常的程序运行过程中,很容易出现、情理可容的异常状况,在一定程度上这种异常的发生是可以预测的,并且一旦发生该异常,就必须采取某种方式进行处理。
不受检查异常:包括RuntimeException及其子类和Error
解析:除了RuntimeException及其子类以外,其他的Exception类及其子类都属于检测异常,当程序中可能出现这类异常,要么使用try-catch语句进行捕获,要么用throws子句抛出,否则编译无法通过。
分析:不受检测异常
为编译器不要求强制处理的异常,检测异常
则是编译器要求必须处置的异常。
Java异常处理机制
Java异常处理本质:抛出异常和捕获异常
1、抛出异常
对于异常情形,已经无法继续下去了,因为在当前环境下无法获得必要的信息来解决问题,你所能做的就是从当前环境中跳出,并把问题交给上一级环境,这就是抛出异常时所发生的事情。抛出异常后,会有几件事随之发生。
2、捕获异常
在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器。潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合。当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适的异常处理器。运行时系统从发生异常的方法开始,依次回查调用栈中的方法,直至找到含有合适异常处理器的方法并执行。当运行时系统遍历调用栈而未找到合适的异常处理器,则运行时系统终止。同时,意味着Java程序的终止。
对于所有的检查异常,Java规定:一个方法必须捕获,或者声明抛出方法之外。也就是说,当一个方法选择不捕捉检测异常时,它必须声明将抛出异常。
3、异常处理五个关键字
try
、catch
、finlly
、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(Exception e){
}catch(Exception e){
}
监控区域
编写多重catch语句块注意事项:
顺序问题:先小后大,即先子类后父类
2、throw
throw
语句抛出
throw ThrowableInstanhce
3、throws
如果一个方法可以导致一个异常但不处理它,它必须指定这种行为以使方法的调用者可以保护他们自己而不发生异常。要做到这点,我们可以在方法声明中包含一个
throws
子句。
public void info() throws Exception{
//
}
4、finally
//假设要捕获多个异常: 从小到大
try {
if (b==0) { //主动的抛出异常 throw throws 一般用于方法
throw new ArithmeticException();
}
System.out.println(a/b);
} catch (Error e) {
System.out.println("Error");
} catch (Exception e) {
System.out.println("Exception");
} catch (Throwable t) {
System.out.println("Throwable");
} finally {
System.out.println("finally");
}//finally 可以不要finally,假设IO,资源,关闭!
try,catch,finally,return 执行顺序
- 执行try,catch,给返回值赋值
- 执行finally
- return
自定义异常
使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承
Exception
类即可。
在程序中使用自定义异常类,大体可分为以下几个步骤:
- 创建自定义异常类。
- 在方法中通过
throw
关键字抛出异常对象。 - 如果在当前抛出异常的方法中处理异常,可以使用
try-catch
语句捕获并处理;否则在方法的声明处通过throws
关键字指明要抛出给方法调用者的异常,继续进行下一步操作。 - 在出现异常方法的调用者中捕获并处理异常。
public class MyException extends Exception{
private int detail;
public MyException(int detail) {
this.detail = detail;
}
//toString
@Override
public String toString() {
return "MyException{" + detail + '}';
}
}
-----------------------------------------------------
public class Test {
//可能存在异常的方法
static void test(int a) throws MyException {
System.out.println("传递的参数为:"+ a);
if (a>10){
throw new MyException(a); //抛出
}
System.out.println("OK");
}
public static void main(String[] args) {
try {
test(11);
} catch (MyException e) {
System.out.println("异常为: "+e);
}
}
}