异常

异常(Exception),例外,程序在运行时出现的异常,如要打开某个文件,而文件不存在;输入非法参数;

异常的结构体系

  • Java把异常当作对象来处理,并定义一个基类 java.lang.Throwable作为所有异常的超类(祖宗类)。
  • Java中异常分为两大类,错误(Error) 和 异常(Exception)

19.异常_变量名

错误(Error)

  • Error类对象由 Java 虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。
  • Java虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。
  • 还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError)、链接错误(LinkageError)。这些错误是不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。

异常(Exception)

Exception分支中有一个重要的子类RuntimeException(运行时异常)

  • ArraylndexOutOfBoundsException(数组下标越界)
  • NullPointerException(空指针异常)
  • ArithmeticException(算术异常)
  • MissingResourceException(丢失资源)
  • ClassNotFoundException(找不到类)等异常,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。

这些异常通常是因为程序逻辑问题引起的,程序应该从逻辑角度尽可能避免这类异常的发生!

ErrorException的区别:

Error通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止线程;Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。

捕获和抛出异常

try 和 catch关键字

  • try 和 catch两个关键字绑定出现

idea快捷键:CTRL + ALT + T (自动生成try catch)

语法:

try{
    //可能出现异常的代码
}catch(需要捕获的异常名 e) {
    //Catch块
}
  • Catch语句中要声明需要捕获的异常类型,当 try 语句块出现异常时 catch 语句块就会被执行。

实例:

public class Demo01 {

    public static void main(String[] args) {
        int a = 5;
        int b = 0;

        try {
            // 输出 a/b 被除数为0,出现ArithmeticException异常
            System.out.println(a/b);
        }catch(ArithmeticException e) {
            System.out.println("出现异常!");
        }
    }
    
}

运行结果出现异常:

Exception in thread "main" java.lang.ArithmeticException: / by zero
	at com.wnaoii.exception.Demo01.main(Demo01.java:9)

finally关键字

  • finally代码块一般用于善后工作,像IO流这些需要关闭的,则可以在finally语句块中关闭
  • 无论异常是否发生,finally代码块都会被执行
  • finally 代码块出现在 catch 代码块最后
  • finally代码块非必要

语法:

try{
    //可能出现异常的代码
}catch(需要捕获的异常名 e){
    //Catch块
}finally{
    //需要执行的代码
}

多重捕获异常

  • 一个 try 之后有多个 catch 代码块,捕获多个异常
  • 捕获的异常同样是顺序执行,由上至下,第一个catch的异常范围应该是小范围的,捕获的范围向下越来越大。(由小到大)

语法:

try{
    // 可能出现异常的代码
}catch(异常类型1 异常的变量名1){
    //Catch块
}catch(异常类型2 异常的变量名2){
    //Catch块
}catch(异常类型3 异常的变量名3){
    //Catch块
}

如果保护代码中发生异常,异常被抛给第一个 catch 块。

如果抛出异常的数据类型与 ExceptionType1 匹配,它在这里就会被捕获。

如果不匹配,它会被传递给第二个 catch 块。

如此,直到异常被捕获或者通过所有的 catch 块。

throws/throw 关键字

  • throw关键字能主动抛出异常,一般在方法中使用。
  • throws关键字是该方法可能抛出异常的声明,throws 关键字放在方法签名的尾部。

例:

public class Demo01 {

    public static void main(String[] args) {
        test(1,0);
    }

    // 定义一个方法
    private static void test(int a,int b) throws ArithmeticException{
        if (b == 0){
            // 事先知道会出现异常主动抛出
            throw new ArithmeticException();
        }
        System.out.println(a/b); 
    }

}