• Java异常处理机制


    异常概述

    ​ Java的异常机制主要依赖于try、catch、finally、throw和throws五个关键字,其中try关键字后紧跟一个花括号扩起来的代码块(花括号不可省略),简称try块,它里面放置可能引发异常的代码。catch后对应异常类型和一个代码块,用于表明该catch块用于处理这种类型的代码块。多个catch块后还可以跟一个finally块,finally块用于回收在try块里打开的物理资源,异常机制会保证finally块总被执行。throws关键字主要在方法签名中使用,用于声明该方法可能抛出的异常;而throw用于抛出一个实际的异常,throw可以单独作为语句使用,抛出一个具体的异常对象。

    异常类的继承体系

    exception

    Java 把所有非正常的情况分为两种:异常(Exception)和错误(Error),它们都继承 Throwable 类。

    异常机制

    ​ 在Java 中表示异常的接口是 Exception, 与其同一层次的还有一个Error接口,用于描述不可挽回的系统级错误,它们两个都继承自 Throwable 接口,这个接口是所有异常和错误的超接口。 在Java 中只有 Throwable 类型的实例才能被 (throw)或者捕获(catch),他是异常处理机制的基本组成类型。

    Error

    ​ Error 是 程序无法处理的错误,表示运行应用程序中发生比较严重的问题。大多数错误与代码编写者的操作无关,而表示代码运行时和 JVM 出现的问题。例如:Java虚拟机运行错误,当 JVM 不再有继续执行操作所需的内存资源时, 将出现 OutOfMemoryError。这些异常发生时,Java虚拟机一般会选择线程终止 。

    Exception

    ​ Java将异常分为两种,Checked异常和Runtime异常, Java认为Checked异常都是可以在编译阶段被处理的异常,所以它强制程序处理所有的Checked异常;而Runtime异常则无须处理。Checked异常可以提醒程序员需要处理所有可能发生的异常。

    Runtime Exception

    ​ 运行时异常 都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。

    Checked Exception

    ​ 非运行时异常(编译异常) 是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常。 当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。

    抛出异常

    抛出异常有三种形式,一是Throws,一个Throw,还有一种系统自动抛异常。下面它们之间的异同。

    Throws

    ​ 使用 Throws 声明抛出异常的思路是,当前方法不知道如何处理这种类型的异常,该异常应该由上一级调用者处理;如果main方法也不知道如何处理这种类型的异常,也可以使用 Throws 声明抛出异常,将异常交由 JVM 处理。JVM对异常的处理方法是,打印异常的堆栈信息,并终止程序运行。

    ​ Throws声明抛出只能在方法中使用,可以抛出多个异常类,多个异常类逗号隔开。

        void exception() throws NullPointerException,
                NumberFormatException, ArrayIndexOutOfBoundsException {
    	
        }
    

    Throw

    ​ 当程序出现错误时,系统会自动抛出异常;除此之外,Java 也允许程序自行抛出异常,自行抛出异常由 Throw 来完成。throw关键字作用是抛出一个异常,抛出的时候是抛出的是一个异常类的实例化对象,

    Throws 和 Throw 使用

    Throws 使用

    /**
     * @author leizige
     */
    public class Math {
    
        public static int div(int a, int b) throws Exception {  //有异常,交给调用方处理
            /* 计算,此处可能出现异常 */
            return a / b;
        }
    
    }
    
    class Test {
        public static void main(String[] args) {
            try {
                int result = Math.div(10, 2);
            } catch (Exception e) {
                /* 打印异常 */
                e.printStackTrace();
            }
        }
    }
    

    因为div使用了throws关键字声明,所以调用此方法的时候,方法必须进行异常处理。通过try...catch;

    主方法抛出异常,交给JVM处理。

    /**
     * @author leizige
     */
    public class Math {
    
        public static int div(int a, int b) throws Exception {  //有异常,交给调用方处理
            /* 计算,此处可能出现异常 */
            return a / b;
        }
    
    }
    
    class Test {
        public static void main(String[] args) throws Exception {
            int result = Math.div(10, 0);
        }
    }
    
    

    运行结果:

    Exception in thread "main" java.lang.ArithmeticException: / by zero
    	at cn.wengzi.exception.Math.div(Math.java:10)
    	at cn.wengzi.exception.Test.main(Math.java:17)
    

    Throw 使用

    public class MyException {
        public static void main(String[] args) {
            try {
                /* 手动抛出异常实例化对象 */
                throw new Exception("66666666");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    Throws 和 Throw 的应用

    例如,现在要使用一个相除的方法,但是在操作之前必须打印“运算开始”的信息,结束之后必须打印“异常结束”。

    /**
     * @author leizige
     */
    @Slf4j
    public class Math {
    
        public static int div(int a, int b) throws Exception {  //有异常,交给调用方处理
            int result = 0;
            /* 计算,此处可能出现异常 */
            log.info("------------计算开始------------");
            result = a / b;
            log.info("------------计算结束------------");
            return result;
        }
    
    }
    
    class Test {
        public static void main(String[] args) {
            try {
                int result = Math.div(10, 0);
                System.err.println("计算结果:" + result);
            } catch (Exception e) {
                System.err.println("错误信息 : " + e);
            }
        }
    }
    

    执行结果:

    16:12:46.188 [main] INFO cn.wengzi.exception.Math - ------------计算开始------------
    错误信息 : java.lang.ArithmeticException: / by zero
    

    以上没有计算结束,因为没有异常发生了,直接中断程序操作。所以做以下操作。

    /**
     * @author leizige
     */
    @Slf4j
    public class Math {
    
        public static int div(int a, int b) {
            log.info("------------计算开始------------");
            int result = 0;
            try {
                /* 计算,此处可能出现异常 */
                result = a / b;
            } catch (Exception e) {
                /* 不抛出异常 */
            }
            log.info("------------计算结束------------");
            return result;
        }
    
    }
    
    class Test {
        public static void main(String[] args) {
            try {
                int result = Math.div(10, 0);
                System.err.println("计算结果:" + result);
            } catch (Exception e) {
                System.err.println("错误信息 : " + e);
            }
        }
    }
    

    执行结果:

    16:15:08.252 [main] INFO cn.wengzi.exception.Math - ------------计算开始------------
    16:15:08.255 [main] INFO cn.wengzi.exception.Math - ------------计算结束------------
    计算结果:0
    
    

    以上代码虽然执行成功了,但是异常并没有抛出去! 因为在方法中已经被自动处理了。所以要抛出异常对象,给方法调用处处理,使用throw关键字。

    /**
     * @author leizige
     */
    @Slf4j
    public class Math {
    
        public static int div(int a, int b) {
            log.info("------------计算开始------------");
            int result = 0;
            try {
                /* 计算,此处可能出现异常 */
                result = a / b;
            } catch (Exception e) {
                throw e;		//抛出异常对象
            }
            log.info("------------计算结束------------");
            return result;
        }
    
    }
    
    class Test {
        public static void main(String[] args) {
            try {
                int result = Math.div(10, 0);
                System.err.println("计算结果:" + result);
            } catch (Exception e) {
                System.err.println("错误信息 : " + e);
            }
        }
    }
    
    

    执行结果:

    16:18:45.405 [main] INFO cn.wengzi.exception.Math - ------------计算开始------------
    错误信息 : java.lang.ArithmeticException: / by zero
    
    
  • 相关阅读:
    【Gerrit】Gerrit与Jenkins/Hudson CI服务器搭建
    【Gerrit】Gerrit cmd query (gerrit命令行查询change信息)
    【python】jiraAPI使用教程 自动创建jira问题单并置状态为OPEN
    【Jenkins】jenkins简单搭建并执行任务
    【python】Redis介绍及简单使用
    【python】PIL 批量绘制图片矩形框工具
    【Flask】Flask快速玩框架
    C# split 几种使用方法
    40个有用的jQuery技术和教程
    jQuery性能优化
  • 原文地址:https://www.cnblogs.com/leizzige/p/14081127.html
Copyright © 2020-2023  润新知