java异常
文章内容发布于 28 天前;最后修改于 20 日前。其中的信息可能发生变化或产生更改,敬请留意。

什么是异常

异常就是在代码运行的时候,程序出现的问题。

我们来看个例子:

int[] arr = {1, 2, 3};
System.out.println(arr[3]);

报错:ArrayIndexOutOfBoundsException

Java中异常的分类

Java.lang.Throwable分为两类,ErrorException

Error表示系统级别的错误,是Java开发公司的使用的。

Exception称之为异常,代表程序可能出现的问题,当程序出现异常的时候,通常使用Exception及其子类封装程序出现的异常。Exception分为两类RuntimeException和其他异常(编译时异常)

RuntimeException及其子类,称之为运行时异常,在编译中不会抛出异常,但在运行时会抛出异常。如上的例子中,数组索引越界就是运行时异常。

编译时异常是在编译阶段就会抛出的异常,在Exception中,除了RuntimeException及其子类,都是编译时异常,必须要手动修改才可以正常编译成字节码文件。

在代码中处理异常

JVM默认的处理异常的方式

JVM在遇到异常的时候,会:

  1. 把异常的原因,异常出现的位置展示在控制台;
  2. 程序运行到出现异常的位置后停止执行(也就是运行到异常存在的语句,异常存在的语句之后的语句全部不执行)

我们可以举例:double num = 1/0;这一句是算数异常:ArithmeticException,属于运行时异常。

System.out.println("Hello World.");
double num = 1/0;
System.out.println("I am a cat.");

当语句中夹杂一个错误运行时异常时,运行情况如下:

可以看到在运行结果中,System.out.println("Hello World.");语句是正常执行的(控制台上打印了这行语句),之后再打印异常的原因,异常出现的位置。打印完异常的信息之后直接退出程序。

在代码中处理(捕获异常)

使用try(用于捕获可能出现异常的代码)、catch(如果出现异常该如何处理)、finally(无论是否发生异常都会执行的代码块,常用于资源清理);需要注意的是,无论代码是否报错,**finally**代码块中的逻辑一定会被执行。

public class YiChang {
    public static void main(String[] args) {
        int[] arr = new int[]{1,2,3};
        try{
            for(int i=0;i<5;i++){
                System.out.println(arr[i]);
            }
        } catch(Exception e){
            System.out.println(e);
        }
        System.out.println("End.");
    }
}

如上代码中,创建了一个只有三个元素的数组,之后使用一个for循环打印,但是循环重复5次,这一定会出现数组越界访问的情况,所以我们将for循环代码用try来捕获,然后如果捕获了异常则打印异常,然后程序会自动继续执行。

trycatchfinally 的语法分别是:

try{<可能会抛出错误的代码>}catch(<报错的类型> e){<处理报错的逻辑>}inally{<一定会执行的逻辑>}

捕获异常的好处:让程序继续按照逻辑运行,提升代码的容错度。

public class YiChang {
    public static void main(String[] args) {
        int[] arr = new int[]{1,2,3};
        try{
            System.out.println(arr[10]);
        } catch(ArrayIndexOutOfBoundsException e){
            System.out.println("Error:ArrayIndexOutOfBoundsException");
        } finally {
            System.out.println("finally");
        }
        System.out.println("End.");
    }
}

如上代码中,当代码运行到System.out.println(arr[10]);时,JVM会创建一个ArrayIndexOutOfBoundsException对象。再把ArrayIndexOutOfBoundsException对象与catch语句中设置的报错对象相对比,检查catch是否能够接收相关异常,如果能接收,则执行能接收对应异常的catch中代码块的逻辑;执行完毕之后,再执行finally语句中代码块的逻辑。

注意点1

try语句的代码块中,如果报错,则不会继续执行接下来的逻辑,如下:

public class YiChang {
    public static void main(String[] args) {
        int[] arr = new int[]{1,2,3};
        try{
            System.out.println("这是在异常之前执行的逻辑");
            System.out.println("这是异常语句" + arr[10]);
            System.out.println("这是在异常之后存在的逻辑");
        } catch(ArrayIndexOutOfBoundsException e){
            System.out.println("这是Catch语句代码块内的语句");
        }
    }
}

注意点2

try中抛出的错误与catch接收的报错不一致时,也就是未被catch,异常会向上一级调用栈传播(但会执行finally中的语句)并抛出报错:

public class YiChang {
    public static void main(String[] args) {
        try{
            System.out.println("这是在异常之前执行的逻辑");
            System.out.println("这是异常语句" + 1/0);
            System.out.println("这是在异常之后存在的逻辑");
        } catch(ArrayIndexOutOfBoundsException e){
            System.out.println("这是Catch ArrayIndexOutOfBoundsException语句代码块内的语句");
        } finally {
            System.out.println("这是finally中的逻辑");
        }
    }
}

注意点3

如果try中的代码没有抛出异常,则代码会完整执行try中的代码,执行完毕try中的代码会执行finally中的代码。由于未抛出异常,所以不会执行catch中的逻辑。

public class YiChang {
    public static void main(String[] args) {
        try{
            System.out.println("这是在异常之前执行的逻辑");
            System.out.println("这是预期异常语句" + 1/1);
            System.out.println("这是在异常之后存在的逻辑");
        } catch(Exception e){
            System.out.println("这是Catch语句代码块内的语句");
        } finally {
            System.out.println("这是finally中的逻辑");
        }
    }
}

注意点4

如果try中的代码被多个catch捕获,如果存在多个catch应该按照从具体到一般的原则排列,如果多个catch块的顺序不正确(即大类在前,小类在后),会导致编译错误。

public class YiChang {
    public static void main(String[] args) {
        try{
            System.out.println("这是在异常之前执行的逻辑");
            System.out.println("这是预期异常语句" + 1/0);
            System.out.println("这是在异常之后存在的逻辑");
        } catch(ArithmeticException e) {
            System.out.println("这是Catch ArithmeticException语句代码块内的语句");
        } catch(Exception e) {
            System.out.println("这是Catch Exception语句代码块内的语句");
        } finally {
            System.out.println("这是finally中的逻辑");
        }
    }
}

说明

在JDK7+版本,如果存在多个catch捕获多个错误,但是错误处理是一样的,则可以|来列举可能出现的错误,官方称呼为多重捕获(multi-catch):

比如:catch(ArithmeticException | ArrayIndexOutOfBoundsException e) {}catch (ArithmeticException | ArrayIndexOutOfBoundsException | NullPointerException e) {}

抛出异常

使用throwsthrow

throws

用途:写在方法定义处,用于声明一个异常,告知调用本方法可能会出现哪些异常。throws中,如果是编译时异常,必须要声明异常,如果是运行时异常,可以选择性的不写。

public void method() throws ArithmeticException, ArrayIndexOutOfBoundsException {
    // 方法的逻辑
}

throw

用途:写在方法内,用于结束方法,手动抛出异常对象,抛出后后续逻辑不再执行。

public void method() {
    // 方法的逻辑
    throw new ArithmeticException;
}

举例:定义一个方法,求数组中的最大的元素。

public class YiChang {
    public static void main(String[] args) {
        int[] arr1 = new int[0];
        try {
            System.out.println(getArrMax(arr1));
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        }
    }
    static int getArrMax(int[] arr)throws NullPointerException, ArrayIndexOutOfBoundsException {
        if (arr==null) {
            throw new NullPointerException();
        }
        if (arr.length==0) {
            throw new ArrayIndexOutOfBoundsException();
        }
        int max = arr[0];
        for(int i=0;i<arr.length;i++){
            if(arr[i]>max){
                max = arr[i];
            }
        }
        return max;
    }
}

在如上的代码中,方法getArrMax会判断是否存在传入为空指针或者数组长度为0,如果存在则使用throw抛出错误,且在方法定义中声明了可能会出现的异常。

如果出现异常,在调用处也需要使用try来捕获异常,否则会以1结束进程,报错退出程序。

自定义异常

  1. 定义异常类
  2. 写继承关系,如果是运行时异常,则继承RuntimeException,如果是编译时异常,则继承Exception
  3. 写空参构造
  4. 写有参构造

自定义异常的意义:就是让控制台报错的信息更清楚、更加符合报错的内容。说的直白一点,自定义异常就是自定义了类名,为了异常的名字

编译时异常:(继承Exception

public class DIYExceptionDemo extends Exception {
    public DIYExceptionDemo() {}
    public DIYExceptionDemo(String message) {
        super(message);
    }
}

运行时异常:(继承RuntimeException

public class DIYRuntimeExceptionDemo extends RuntimeException {
    public DIYRuntimeExceptionDemo() {}
    public DIYRuntimeExceptionDemo(String message) {
        super(message);
    }
}
文章「java异常」,由本站用户「admin」发布。文章仅代表admin观点,不代表本站立场。
页面网页地址「https://xiaozhiyuqwq.top/p/2900」。
如您对文章及其附件提出版权主张,或进行引用转载等,请查看我们的【版权声明】
本页面暂时没有评论......

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇