java-异常

一、异常的概念及分类

Exception:异常,代表程序可能出现的问题

Exception分为两类:

1、运行时异常RuntimeException以及其子类,编译阶段不会出现异常提醒,在运行阶段会出现异常提醒

2、编译时异常:编译阶段出现异常提醒

二、异常处理的方式

1、JVM默认的处理方式

把异常的原因、异常的名称、异常出现的位置以红色字体打印在控制台

程序停止执行,异常后面的代码不会再执行

public class test1 {
    public static void main(String[] args) {
        /*
            1、JVM默认的处理方式
            把异常的原因、异常的名称、异常出现的位置以红色字体打印在控制台
            程序停止执行,异常后面的代码不会再执行
        */
        System.out.println("你好");
        System.out.println(1/0);
        System.out.println("我的世界");
        System.out.println("java");
        // 你好
        // ArithmeticException
        // 只会输出你好和异常信息 出现异常后面的代码不会再执行
    }
}

2、自己处理捕获异常

如果自己不捕获并处理异常 系统就会处理异常 那么就在控制台输出错误信息 并终止程序 如果我们不想要终止程序就必须自己捕获并处理异常 这就是自己捕获并处理异常的好处

(1)语法

try{

        可能出现异常的代码;

} catch(异常类名 变量名){

        异常的处理代码;

}

快捷键:

选中可能出现异常的代码 ctrl+alt+t

目的:

当代码出现异常时,可以让程序继续往下执行

public class test1 {
    public static void main(String[] args) {
        /*
            2、自己处理
            语法:
            try{
                可能出现异常的代码;
            } catch(异常类名 变量名){
                异常的处理代码;
            }
        */
        System.out.println("我的世界");
        /*
            此处出现算术异常,程序会创建一个码ArithmeticException类的对象 new ArithmeticException()
            然后拿着这个对象与catch的小括号中的对象进行对比 看是否匹配
            如果能接收 那么异常就会捕获 就会执行catch里面的代码
            当执行完try...catch后 程序会继续往下执行 输出java
        */
        try {
            // 可能出现异常的代码
            System.out.println(1/0);
        }catch (ArithmeticException e){
            // 出现异常代码后执行的操作
            System.out.println("算术异常 被除数不能是0");
        }
        // 执行完try...catch后 程序会继续往下执行
        System.out.println("java");
        
        // 输出:
        // 我的世界
        // 算术异常 被除数不能是0
        // java
    }
}

(2)注意

1、如果try中代码没有出现异常,那么系统会执行完try中所有的代码,不会执行catch语句体(只有try语句体出现异常才会执行catch语句体)

public class test1 {
    public static void main(String[] args) {
        /*
            2、自己处理
            语法:
            try{
                可能出现异常的代码;
            } catch(异常类名 变量名){
                异常的处理代码;
            }
        */
        try {
            // 可能出现异常的代码
            // 当没有出现异常时 会执行完所有的代码
            System.out.println("你好");
            System.out.println("java");
        }catch (ArithmeticException e){
            // 出现异常代码后执行的操作
            // 当没有出现异常时 不会执行代码
            System.out.println("算术异常 被除数不能是0");
        }
        // 执行完try...catch后 程序会继续往下执行
        System.out.println("我的世界");
        // 输出:
        // 你好
        // java
        // 我的世界
    }
}

2、如果try中代码有多个异常,但是catch中罗列的异常情况没有包括try中的所有异常,程序可能终止,可能不终止

如果程序没有捕获到异常就会终止程序(相当于try...catch白写了 最终还是交给虚拟机进行处理) 如果捕获到了就不会终止程序

public class test1 {
    public static void main(String[] args) {
        /*
            2、自己处理
            语法:
            try{
                可能出现异常的代码;
            } catch(异常类名 变量名){
                异常的处理代码;
            }
        */
        int [] arr=new int[] {1,2,3,4,5};
        try {
            // 可能出现异常的代码
            System.out.println(arr[10]);
            System.out.println(1/0);
        }catch (ArithmeticException e){
            // 出现异常代码后执行的操作
            System.out.println("算术异常 被除数不能是0");
        }

        System.out.println("我的世界"); // 因此不会输出我的世界
        /*
            分析:System.out.println(arr[10]);出现了索引异常 就会与catch括号中的异常进行匹配
            现在 ArithmeticException e 与 new ArrayIndexOutOfBoundsException()无法匹配
            错误捕获不到
            由于 ArrayIndexOutOfBoundsException 异常没有在 catch 块中被捕获处理,程序会在此处中断,不会继续执行后面的代码
        */
        // 输出:
        // ArrayIndexOutOfBoundsException
    }
}
public class test1 {
    public static void main(String[] args) {
        /*
            2、自己处理
            语法:
            try{
                可能出现异常的代码;
            } catch(异常类名 变量名){
                异常的处理代码;
            }
        */
        int [] arr=new int[] {1,2,3,4,5};
        try {
            // 可能出现异常的代码
            System.out.println(1/0);
            System.out.println(arr[10]);
        }catch (ArithmeticException e){
            // 出现异常代码后执行的操作
            System.out.println("算术异常 被除数不能是0");
        }

        System.out.println("我的世界"); 
        /*
            分析:System.out.println(1/0);出现了算术异常 就会与catch括号中的异常进行匹配
            因此trySystem.out.println(arr[10]);就不会执行(即使有错误也执行不到)
            现在 ArithmeticException e 与 new ArithmeticException()匹配
            错误捕获到 由于捕获到错误就会执行catch的语句体
            执行完try...catch之后 程序继续往下执行 输出我的世界
        */
        // 输出:
        // 算术异常 被除数不能是0
        // 我的世界
    }
}

解决方法:写多个catch语句罗列所有的异常情况,如果这些异常存在父子关系,那么父类一定要写在最下面

根据多态的概念 父类可以接收子类的对象 如果将父类异常放在上面 那么try语句体出现的异常都会被父类异常接收 那么父类异常下面的异常永远执行不到

在JDK7以后 如果多个catch的语句体执行的操作是一样的 那么异常可以写在一个catch语句体中

注意:写在同一个catch括号中的异常不能存在父子关系 各个异常之间用|隔开 不能用||隔开

public class test1 {
    public static void main(String[] args) {
        /*
            2、自己处理
            语法:
            try{
                可能出现异常的代码;
            } catch(异常类名 变量名){
                异常的处理代码;
            }
        */
        int [] arr=new int[] {1,2,3,4,5};
        try {
            // 可能出现异常的代码
            // 每次只捕获一个错误 捕获到了就执行catch语句体
            System.out.println(1/0);
            System.out.println(arr[10]);
        }catch (ArrayIndexOutOfBoundsException |ArithmeticException e){
            // 不能写成ArrayIndexOutOfBoundsException ||ArithmeticException e
            // 或者ArrayIndexOutOfBoundsException e|ArithmeticException e
            // 出现异常代码后执行的操作
            System.out.println("异常");
        }
        System.out.println("我的世界"); // 为什么不能输出
    }
}

(3)问题总结

(4)对异常常见的处理方法

1、异常对象名称.getMessage();

该方法返回有关异常的简短描述

public class test1 {
    public static void main(String[] args) {
        /*
            2、自己处理
            语法:
            try{
                可能出现异常的代码;
            } catch(异常类名 变量名){
                异常的处理代码;
            }
        */
        int [] arr=new int[] {1,2,3,4,5};
        try {
            System.out.println(arr[10]);
        } catch (ArrayIndexOutOfBoundsException e) {
            // e.getMessage() 返回值是有关异常的简短描述
            String str= e.getMessage();
            System.out.println(str);
        }
        System.out.println("我的世界");
        // Index 10 out of bounds for length 5
        // 我的世界
    }
}

2、异常对象名称.toString();

该方法返回有关异常的简短描述

public class test1 {
    public static void main(String[] args) {
        /*
            2、自己处理
            语法:
            try{
                可能出现异常的代码;
            } catch(异常类名 变量名){
                异常的处理代码;
            }
        */
        int [] arr=new int[] {1,2,3,4,5};
        try {
            System.out.println(arr[10]);
        } catch (ArrayIndexOutOfBoundsException e) {
            // e.getMessage() 返回值是有关异常的简短描述
            String str= e.toString();
            System.out.println(str);
        }
        System.out.println("我的世界");
        // java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 5
        // 我的世界
    }
}

3、异常对象名称.printStackTrace();

无返回值 直接在控制台以红色字体打印异常信息 不会终止程序

3、抛出异常

用于方法中可能出现的异常

(1)throws

写在方法的定义处,表示声明一个异常,告诉调用者使用本方法可能会有哪些异常,如果是运行时异常,那么throws在方法定义处抛出的异常可以不写,但如果是编译时异常,那么throws在方法定义处抛出的异常必须要写

语法:

public void 方法() throws 异常类名1,异常类名2...{

        ....

}

(2)throw

写在方法内,结束方法,手动抛出异常对象,交给调用者,方法中异常下面的代码就不再执行力

语法:

public void 方法() {

        throws 异常类名1,异常类名2...

}

public class test1 {
    public static void main(String[] args) {
        // 对抛出的异常 我们需要进行处理 可以采取自己捕获错误的方式 try...catch
        int [] arr=new int[0];
        try {
            System.out.println(getMax(arr));
        } catch (NullPointerException e) {
            System.out.println("空指针异常");
        }catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组越界访问异常");
        }
    }
    // throws NullPointerException,ArrayIndexOutOfBoundsException
    // 这段代码告诉调用者 调用getMax方法可能会出现NullPointerException,ArrayIndexOutOfBoundsException的错误
    // 因为NullPointerException,ArrayIndexOutOfBoundsException都属于运行时异常RuntimeException
    // 因此在方法头定义处可以不写throws NullPointerException,ArrayIndexOutOfBoundsException
    public static int getMax (int [] arr)throws NullPointerException,ArrayIndexOutOfBoundsException{
        // 当数组为null意味着该数组变量不指向任何数组的内存地址
        if(arr==null){
            // 抛出空指针异常给调用者
            throw new NullPointerException();
        }
        // 当没有数组元素时 抛出索引越界异常
        if(arr.length==0){
            // 抛出索引越界异常给调用者
            throw new ArrayIndexOutOfBoundsException();
        }
        int max=arr[0];
        for (int i = 1; i < arr.length; i++) {
            if(arr[i]>max){
                max=arr[i];
            }
        }
        return max;
    }
}

抛出异常通常和捕获异常相结合

三、自定义异常

创建步骤:

1、定义异常类

类名见名知意

2、写继承关系

如果是编译时异常就继承Exception

如果是运行时异常就继承RuntimeException

3、定义空参构造

4、定义带参构造

  • 20
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值