4、异常处理


异常概述

System.out.println(1/0);
System.out.println("呵呵");

//这段代码编译是可以通过的,但是运行的时候就出问题了,这种异常被称为运行时异常
//JVM帮我们捕获到异常
/*Exception in thread "main" java.lang.ArithmeticException: / by zero
	at com.xjt.demo01.ExceptDemo.main(ExceptDemo.java:5)
这一段报错信息中,前面告诉你出现了xxxx错误.
后一段告诉你在哪一行出的错误
*/

那么异常是如何产生的呢?

在运行到 1/0 的时候. 程序会创建一个异常对象对外抛出,然后被 JVM 捕获. JVM 也不知道怎么办. 就丢了出来,最终显示给用户了. 如果没有人处理异常, 程序会被中断. 这也是为什么我们没有看到”呵呵”两个字的原因

  • 程序产生错误对象的过程被称为抛异常;
  • 获取到这个错误信息. 被称为捕获异常;

异常分类

程序的错误千奇百怪,有的编译的时候就告诉你错了, 有的得运行起来才告诉你错了. 那我们就对异常进行分类.
分类之前, 我们想这么一个事儿,异常是错误对象,那有对象一定有类啊,对吧,异常类都有哪些呢?
image.png
异常类的根: Throwable
两个分支: Error 和 Exception
Exception 又分为 RuntimeException 和其他 Exception
RuntimeException 表示运行时异常
其他 Exception: 不用运行就知道错了
Error: 表示严重的问题 合理的应用程序不应该试图捕获. 程序员一般不好处理.
Error, Exception, RuntimeException 的区别:
RuntimeException: 运行时异常, 可以不用主动去处理. 就好比,开车上山, 路上很多的小石子, 不可能把每个小石子都处理掉吧. 等着小石子把轮胎扎破了. 再修就是了
Exception: 异常. 必须要手动处理. 还是开车上山, 路上突然出现一个大石头在前面. 你不把石头拿走. 你上不了山.
Error: 系统错误,这个就比较狠了。你开车上山 山塌了……你是解决不了的 只能避免 怎么避免? 换个山呗

区分编译时异常和运行时异常

image.png
补充:
编译时异常就是在 IDEA 等编译器中写的代码有异常时飘红,需要我们手动处理;
运行时异常,如 1/0 编译器不会飘红,但是运行时会报错;

如何查看某个异常属于编译时异常和运行时异常呢?
image.png
image.png

Throwable 成员方法

方法 描述 示例
public String getMessage() 返回此 throwable 的详细消息字符串 public String getMessage()

返回此 throwable 的详细消息字符串。  
Index 3 out of bounds for length 3 |
| public void printStackTrace() | 将此 throwable 及其回溯打印到标准错误流。 此方法在错误输出流上打印此 Throwable 对象的堆栈跟踪,该字段为 System.err 字段的值。 第一行输出包含此对象的 toString()方法的结果。 剩余行表示先前由方法 fillInStackTrace()记录的数据。 此信息的格式取决于实现,但以下示例可能被视为典型:   | java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
at com.xjt.demo01.ExceptDemo.method(ExceptDemo.java:26)
at com.xjt.demo01.ExceptDemo.main(ExceptDemo.java:20) |
| public String toString() | 返回此 throwable 的简短描述,
结果是连接:   1)这个对象的类的 name  
2)”:”(冒号和空格)   3)调用此对象的 getMessage()方法的结果 | java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3 |

异常处理

try…catch…

image.png
示例:

public class ExceptDemo {
    public static void main(String[] args) {
        System.out.println("开始");
        method();
        System.out.println("结束");
    }
    public static void method(){
        try {
            int[] arr = {11,22,33};
            System.out.println(arr[3]);
        }catch (ArrayIndexOutOfBoundsException e){
            e.printStackTrace();
            System.out.println(e.getMessage());
            System.out.println(e.toString());
        }
    }
}

打印结果:

开始
Index 3 out of bounds for length 3
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
结束
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
	at com.xjt.demo01.ExceptDemo.method(ExceptDemo.java:4)
	at com.xjt.demo01.ExceptDemo.main(ExceptDemo.java:10)

try…catch…finally

try {
   ...  //监视代码执行过程,一旦返现异常则直接跳转至catch,
        // 如果没有异常则直接跳转至finally
} catch (SomeException e) {
    ... //可选执行的代码块,如果没有任何异常发生则不会执行;
        //如果发现异常则进行处理或向上抛出。
} finally {
    ... //必选执行的代码块,不管是否有异常发生,
        // 即使发生内存溢出异常也会执行,通常用于处理善后清理工作。
}

throws

image.png
有时候出现的异常时我们解决不了的,要通过 throws 将异常抛出去,由调用者解决(try…catch…)。
IDEA 工具使用 Alt+Enter 快速生成声明抛出异常 throws,
它运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常
使用格式:

修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2 ... { }

image.png

throws 和 throw 的区别

image.png

自定义异常

image.png
示例:

//ScoreException.java
public class ScoreException extends Exception{
    public ScoreException() {
    }

    public ScoreException(String message) {
        super(message);
    }
}

//MyDefineExcept.java
public class MyDefineExcept {
    public void checkScore(int score) throws ScoreException {
        if(score<0 || score>100){
            throw new ScoreException("你给的分数有误,0<=score<=100");
        }else{
            System.out.println("分数正常");
        }
    }

    public static void main(String[] args) {
        MyDefineExcept mde = new MyDefineExcept();
        try {
            mde.checkScore(120);
        } catch (ScoreException e) {
            e.printStackTrace();
        }
    }
}

文章作者: CoderXiong
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 CoderXiong !
  目录