目录
异常
1.Java中异常的体系结构
2.异常的处理
3.自定义异常类
异常
在Java中,将程序执行过程中发生的不正常行为称为异常,C语言中没有这个概念,接下来我们重点需要掌握异常处理体系(try, catch, throw, finally)以及如何自定义异常类。
1.Java中异常的体系结构
异常的种类繁多,Java内部维护了一个异常的体系结构如下:
Java中可以说是把所有的异常体系都封装了起来,在程序中遇到各种问题时,JVM会直接定位异常情况并在控制台提示。
其中Throwable是异常体系的顶层类,它的内部实现了让Java虚拟机抛出错误的代码。他派生出两个重要的子类Error和Exception。
Error:指的是Java虚拟机无法解决的严重问题,比如JVM的内部错误,资源耗尽等,典型代表:StackOverflowError和OutOfMemoryError。
Exception:异常产生后程序员可以通过代码进行处理的异常,使程序继续运行。
2.异常的处理
Exception异常的子类可以分为两种,一种是RunTimeException类,我们称为是运行时异常,其余的异常我们都称为是编译时异常。下面是异常处理的注意事项:
- 我们可以在方法体内部通过throw抛出一个Exception异常,异常一旦抛出后续代码就不会执行,我们可以通过异常捕获来使后续代码可以继续执行。
- 只有Exception异常和它的子类能被处理。
- 如果抛出的是运行时异常或者运行时异常的子类,可以不用处理,直接交给JVM来处理。
- 如果抛出的是编译时异常,用户必须处理,否则就无法通过编译。
异常的处理流程:
1.throws声明异常
public void OpenConfig(String filename) throws FileNotFoundException{
if(filename.equals("config.ini")){
throw new FileNotFoundException("配置文件名字不对");
}
// 打开文件
}
一般在定义类的时候使用 ,如果方法内部抛出多个异常。throws后面必须跟多个异常类型,也可以直接声明他们的父类。
throws声明异常并没有进行处理,而是留给了调用者进行处理,调用者在调用声明抛出异常的方法时,必须对该异常进行处理,或者继续使用throws抛出。
2.try-catch捕获并处理
try {
int[] array = {1,2,3};
System.out.println(array[3]); // 此处会抛出数组越界异常
}catch (NullPointerException e){ // 捕获时候捕获的是空指针异常--真正的异常无法被捕获到
e.printStackTrace();
}
如上所示,try中存在异常代码,catch用来捕获异常,并通过printStackTrace()方法来打印该异常的详细信息。
3.try-catch-finally语句
在实际应用中,异常的出现具有不确定性,那就导致了在try语句中异常出现位置之后的剩余代码面临着一个问题,如果该异常抛出了,剩余代码就不执行,没抛出就执行,写程序时有些代码我们希望无论程序是否发生异常都需要被执行,因此Java引入了finally语句。
语法格式:
try{
// 可能会发生异常的代码
}catch(异常类型 e){
// 对捕获到的异常进行处理
}finally{
// 此处的语句无论是否发生异常,都会被执行到
}
// 如果没有抛出异常,或者异常被捕获处理了,这里的代码也会执行
finally 执行的时机是在方法返回之前(try 或者 catch 中如果有 return 会在这个 return 之前执行 finally). 但是如果finally 中也存在 return 语句, 那么就会执行 finally 中的 return, 从而不会执行到 try 中原有的 return.
3.自定义异常类
class UserNameException extends Exception {
public UserNameException(String message) {
super(message);
}
}
class PasswordException extends Exception {
public PasswordException(String message) {
super(message);
}
}
tips:
- 继承自Exception的异常默认是受查异常(编译时异常)
- 继承自RuntimeException的异常默认为非受查异常(运行时异常)