JAVA异常处理(三种异常处理机制)

 2022-09-16
原文地址:https://blog.csdn.net/weixin_65243968/article/details/125784591

前言

异常是程序在 编译执行 的过程中可能出现的问题,语法错误不算在异常体系

提前处理异常,程序会更加安全


一、异常体系

202209162100144981.png

Error:

系统级别问题、JVM退出等,代码无法控制

Exception:

Java.lang包下,称为异常类,它表示程序本身可以处理的问题

Runtime Exception及其子类:

运行时异常,编译阶段不会报错(如空指针,数组索引越界异常)

除Runtime Exception之外所有异常:

编译时异常,编译期必须处理的,否则程序不能通过编译(如日期格式化)


二、 异常示例

1.运行时异常

编译阶段不会报错,运行时才会提示错误

    public static void main(String[] args) {
    
        //数组索引越界异常:ArrayIndexOutOfBoundsException
        int[] arr = {1, 2, 3};
        System.out.println(arr[3]);
    
        //空指针异常:NullPointerException,直接输出没问题,但是调用空指针的变量功能就会报错
        String name = null;
        System.out.println(name);          //可以输出
        System.out.println(name.length()); //报错
    
        //类型转换异常:ClassCastException
        Object o = 12;
        String s = (String) o;
    
        //数学操作异常:ArithmeticException
        int c = 10/0;
    
        //数字转换异常:NumberFormatException
        String number = "a2";
        Integer i = Integer.valueOf(number);
    }

2.编译时异常

编译阶段就报错,必须要处理

如下图,日期解析异常

202209162100156832.png


三、异常处理

1.默认异常处理

通常我们不对代码可能出现的异常进行处理,Java就会默认处理我们的异常,如下:

默认会在出现异常的代码处,自动创建一个异常对象:ArithmeticException

异常会从方法中出现的抛给调用者,调用者抛给JVM虚拟机

虚拟机收到异常对象后,先在控制台输出异常栈信息数据

直接从出现异常的地方关闭程序

2.异常处理1 & throws

添加throws ***到方法签名

规范写法 throws Exception

将方法内部出现的异常抛给本方法调用者

throws仅仅是将函数中可能出现的异常向调用者声明,而自己则不具体处理。

throws声明:如果一个方法内部的代码会抛出检查异常(checked exception),而方法自己又没有完全处理掉或并不能确定如何处理这种异常,则javac保证你必须在方法的签名上使用throws关键字声明这些可能抛出的异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理,否则编译不通过。

    public static void main(String[] args) throws ParseException {
        parseTime("2015-10-10 10:10:10");
        }
    
        public static void parseTime(String data) throws ParseException {
    
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
            Date d = sdf.parse(data);
        }

3.异常处理2 & try . . . catch . . .

监视捕获异常,用在方法内部,可以将方法内部出现的异常直接捕获处理

发生异常的方法自己独自完成异常处理,程序还能继续往下执行

202209162100164413.png

    public static void main(String[] args)  {
    parseTime("2015-10-10 10:10:10");
    }
    
    public static void parseTime(String data)  {
    
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
            Date d = sdf.parse(data);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

4.异常处理3 & 前面两者的结合

方法将异常通过throws抛给调用者,调用者收到异常后捕获处理。

    public static void main(String[] args)  {
        try {
            parseTime("2015-10-10 10:10:10");
            System.out.println("成功");
        } catch (ParseException e) {
            e.printStackTrace();
            System.out.println("失败");
        }
    }
    
    public static void parseTime(String data) throws ParseException {
    
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
        Date d = sdf.parse(data);
    }

5.运行时异常的处理

可以不进行处理,编译阶段不会报错,但建议处理,在最外层捕获

    public static void main(String[] args) {
    	System.out.println("开始");
        try {
            int d = 10/0;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        System.out.println("结束");
    }

四、自定义异常

JAVA无法为所有的问题提供异常类,如果企业想通过异常的方式来管理某个业务问题,就需要自定义异常类了。

按照国际惯例,自定义的异常应该总是包含如下的构造函数:
一个无参构造函数
一个带有String参数的构造函数,并传递给父类的构造函数。
一个带有String参数和Throwable参数,并都传递给父类构造函数。
一个带有Throwable 参数的构造函数,并传递给父类的构造函数。

注意: 如果自定义异常是为了提示,在使用的时候,一定要用try..catch,不要直接用throw往外抛。

自定义编译时异常

定义一个异常类继承Exception

重写构造器

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

在出现异常的地方用throw new自定义对象抛出

     public static void checkAge(int age) throws Ageilleagaleception {
            if(age < 0 || age > 200){
                throw new Ageilleagaleception(age+"is illegal");
            }else {
                System.out.println("年龄正确");
            }
        }

自定义运行时异常

定义一个类继承RuntimeException

重写构造器

在出现异常的地方用throw new自定义对象抛出

总结

程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常

异常处理不能替代简单的测试,不要过分的细化异常