• Java 中的异常


    1. 不处理异常:如果代码发生异常,而没有进行 try...catch 则代码执行到此处就直接中断了,不会继续执行了。由于没有异常处理器,则这个异常被throw给了JVM,JVM处理异常的方法是:调用异常的 printStackTrace 方法,在标准输入设备中打印出上面的信息,然后JVM就shutdown了。

        public void exception(){

            int a = 1 / 0;

            System.out.println("exception end.");

        }

    例如这个方法,没有进行异常处理,则JVM打印一下信息:

    Exception in thread "main" java.lang.ArithmeticException: / by zero

        at org.hello.ExceptionBlock.exception(ExceptionBlock.java:13)

        at org.hello.ExceptionBlock.main(ExceptionBlock.java:8)

    打印了异常发生的线程,异常类型,异常消息,调用堆栈。

            System.err.print("Exception in thread ""

                     + t.getName() + "" ");

    e.printStackTrace(System.err);

    }

    对于这种未经处理的异常:

    ① 初始化一个异常对象

    ② JVM在异常发生的线程上调用,

    /**

    * Dispatch an uncaught exception to the handler. This method is

    * intended to be called only by the JVM.

    */

    private void dispatchUncaughtException(Throwable e) {//e就是第一步初始化好的参数。

    getUncaughtExceptionHandler().uncaughtException(this, e);

    // 获得一个线程默认的异常处理器(getUncaughtExceptionHandler())。调用该异常处理器的uncaughtException方法

    }

    2, try...catch 处理异常

    例如:

        public static void exce1(){

            int a = 0;

            try{

                int b = Integer.parseInt("0");

                a = 1 / b;

                // 由于上面的语句发生了异常,所以下面的语句没有机会执行

                System.out.println("a = 1 / b");

            }catch(Exception e){

                a = -1;

                e.printStackTrace();

            }

            // 异常在catch块中处理完毕,这条语句就可以正常执行了。

            System.out.println("exce1 end.");

        }

    在这里处理了异常,是的a具有合法的值,异常catch块执行完毕之后,相当于异常成功处理了,所以下面的 System.out.println("exce1 end."); 语句也就可以正常执行了。

    3. try...catch..finally

        public static void exce1(){

            int a = 0;

            try{

                int b = Integer.parseInt("0");

                a = 1 / b;

                System.out.println("a = 1 / b");

            }catch(Exception e){

    //在catch块中发生了异常,所以下面的语句 不会执行,            

                a = 1/0;

                e.printStackTrace();

            }finally{

            // 这里的finally块在所有的catch块都执行完毕之后执行

                System.out.println("finally before.");

                System.out.println("finally end.");

            }

            // 由于没有catch上面的异常,则下面的语句不会被执行

            // 如果在catch块中没有异常,则下面的语句就可以正常执行

            System.out.println("exce1 end." + a);

        }

    4. Throwable类

    这个类其实就是JVM处理错误和异常的接口,也可以认为是JVM通知程序的一种机制。这个类及其子类都可以在 catch 语句中出现

            try {

                int b = Integer.parseInt("hello");

                int a = 123 / 0;

            }catch(ArithmeticException e){

                e.printStackTrace();

            }catch (NumberFormatException e) {

                e.printStackTrace();

            }catch(Throwable o){

                

            }finally{

                System.out.println("finally end.");

            }

    而且常常是JVM来初始化这些类的对象,然后这一个一个的catch块就成了一个一个的异常处理器。当发生异常时,JVM首先初始化好异常对象,然后通过异常对象的类型和注册的异常处理器的类型对比,如果匹配则调用该处理器处理异常,最后执行finally块的代码,此时这个异常就被处理完毕。处理异常的流程:

    ① JVM初始化异常对象

    ② 匹配执行对象的异常处理器,如果没有匹配到则该异常直接抛向jvm,jvm使用默认的方式处理异常:打印异常信息,终止线程,JVM退出。

    ③ 如果上面的匹配到了异常处理器,最终执行完毕之后执行finally块

    至此,一个抛出的异常就处理完毕了,程序可以继续向下执行了。

    5. 当catch到一个异常时,如何处理

    在Throwable类的描述,举了一个例子:

    try {

        // 比如DAO中的数据库操作,出现异常

    lowLevelOp();

    } catch (LowLevelException le) {

        // 初始化一个自定义的异常,将其抛到业务层。

        // 业务层,根据业务逻辑来处理该异常。

    throw new HighLevelException(le); // Chaining-aware constructor

    }

    在分层的架构下:例如WEB MVC中,如果一层抛出了异常但是没法处理(常常是不知道如何处理,或者说在这个处理不合适)那就封装一层往上抛。

     

    6. 异常的分类

    checked异常和unchecked异常

    Exception类及其子类(除了java.lang.RuntimeException类)都是checked异常,当我们throw一个这种类型的异常时必须处理,而java.lang.RuntimeException类,则是unchecked异常,这种类型的异常可以不用强制处理:

    public class TestException {

        public static void main(String[] args) {

            String res = "";

            res = findUserName("hello");

            System.out.println(res);

            

            res = findUserName("");

            System.out.println(res);

            

    //        try {

    //            res = findPassword("");

    //        } catch (PasswordIsInvalid e) {

    //            e.printStackTrace();

    //        }

        }

        

        public static String findUserName(String params){

            

            if(null == params || "".equals(params)){

    // UserNameIsInvalid是unchecked的异常,所以不需要处理

                throw new UserNameIsInvalid("参数无:-D");

            }

            

            return "xxx";

        }

        

        public static String findPassword(String params) throws PasswordIsInvalid{

            

            if(null == params || "".equals(params)){

    // 这里抛出了一个checked异常,所以要进行处理,所以要在方法上throws这个异常

                throw new PasswordIsInvalid("参数无:-D");

            }

            

            return "xxx";

        }

    }

     

    @SuppressWarnings("serial")

    class PasswordIsInvalid extends Exception{

        public PasswordIsInvalid(String message) {

            super(message);

        }

    }

     

    @SuppressWarnings("serial")

    class UserNameIsInvalid extends RuntimeException{

        public UserNameIsInvalid(String message) {

            super(message);

        }

    }

  • 相关阅读:
    Spring Boot 快速入门
    mySql 主从复制linux配置
    Neural Networks for Machine Learning by Geoffrey Hinton (1~2)
    DIV浮动IE文本产生3象素的bug
    Leet Code OJ 338. Counting Bits [Difficulty: Medium]
    Unity3D:Gizmos画圆(原创)
    科学世界的人文关怀:开源科学与人工智能
    使用c#訪问Access数据库时,提示找不到可安装的 ISAM
    Android API Guides---Services
    《从0到1》读书笔记第一章"未来的挑战"第2记:做老子还是做孙子
  • 原文地址:https://www.cnblogs.com/a-ray-of-sunshine/p/4642883.html
Copyright © 2020-2023  润新知