• JAVA篇:Java异常


    1、异常简介

    异常就是有异于常态,和正常情况不一样,有错误产生。在Java中,阻止当前方法或作用域的情况,称之为异常。Java中所有的异常类都继承自Throwable类。

      Thowable类是Java语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过Java虚拟机或者Java throw语句抛出,其实现子类包含ErrorException

      ErrorThrowable的子类,用于指示合理的应用程序不应该试图捕获的严重问题,大多数这样的错误都是异常条件。在执行该方法期间,无需在其throws自居中声明可能抛出但是未能捕获的Error的任何子类,因为这些错误可能是再也不会发生的异常条件。一旦Error出现,程序就彻底的挂了,被称为程序终结者,包括了虚拟机错误和线程死锁。

      Exception类及其子类是Throwable的一种形式,它指出了合理的应用程序想要捕获的条件,也就是通常所说的“异常”。主要指编码、环境、用户输入操作出现问题。Exception主要包括两大类:非检查异常(RuntimeException)和检查异常(其他的一些异常)。

    2、try-catch-finally语句

    2.1 try语句块

    负责捕获异常,一旦try块中发生了异常,程序的控制权将被移交给catch块中的异常处理程序。try语句块不可以独立存在,必须与catch或者finally块同存。

    2.2 catch语句块

    catch语句捕获相应的异常,进行发出警告、提示、检查配置、网络连接、记录错误等相应处理。catch块执行完毕之后跳出catch块,继续执行后面的代码。

    当使用多个catch处理不同的异常类,要按照先catch子类后catch父类的处理方式,因为其处理异常的原则是:由上而下,就近处理

    2.3 finally语句块

    无论是正常执行try语句块结束还是移交异常处理catch块执行结束返回前,必须处理定义在finally中的语句。所以finally语句块中一般用于关闭和释放资源。

    2.4 try-catch-finally流程和return

            int a=-1;
    ​
            try {
                System.out.println("in try");
                //a = 1/0; //当抛出异常时,转到catch语句
                a = 1;//若未抛出异常,继续调用finally中的语句
           
    ​
            }catch (Exception e){
                System.out.println("in catch");
                e.printStackTrace();//运行完毕后调用finally中的语句
            }finally {
                System.out.println("in finally");
    ​
            }
            System.out.println("finish");//catch块运行完毕后继续运行后续语句
            return a;

    正常运行时的输出:

    in try
    in finally
    finish
    1

    抛出异常时的输出:

    java.lang.ArithmeticException: / by zero
    in try
    in catch
        at liwx.learning.Exceptest.test(Exceptest.java:14)
    in finally
    finish
        at liwx.learning.Exceptest.main(Exceptest.java:6)
    -1

    finally中return 覆盖问题:执行try结束(返回前--如果有return),记录返回值,去运行finally,如果此时finally中有return,则覆盖,catch同理。如下代码,返回的结果是3.

        try {
                System.out.println("in try");
                return 1;
    ​
            }catch (Exception e){
                System.out.println("in catch");
                e.printStackTrace();
                return 2;
            }finally {
                return 3;
            }

    3、throw和throws关键字、自定义异常

    throw关键字是一个抛出异常的动作,而throws用于声明某个方法可能会抛出的异常(可声明多种异常,用逗号分隔),然后交给上层调用该方法的程序处理。但是两者做的部分都是在发现异常后进行抛出(或声明),将异常的处理丢给上层处理。

    //自定义异常
    class MyException extends Exception{
        MyException(){
            super();
        }
        MyException(String str){
            super(str);
        }
    }
    //声明异常、抛出异常
    public static void check(int a) throws MyException,Exception {
            if(a<0) {
                throw new  MyException("超出限制下限!");
            }
    ​
            if(a>1) {
                throw new  MyException("超出限制上限!");
            }
        }
     //调用方法并处理异常
        try {
                check(-1);
            }catch (MyException e){
                e.printStackTrace();
            }catch (Exception e){
                e.printStackTrace();
            }

    前面自定义了一个异常类MyException

    在Java中我们可以自定义异常,但是在编写自己的异常类的时候需要注意:

    • 所有的异常都必须是Throwable的子类。

    • 如果希望写一个检查性异常类,则需要继承Exception

    • 如果想写一个运行时异常类,那么需要继承RuntimeException

    若是自定义异常类来处理特定问题,那么就需要自己完成发现异常、抛出异常以及处理异常的一整套工作,会增加一些开发成本和工作量,那么为什么会需要用到自定义异常呢?

    1. 当作为团队进行项目开发时,使用自定义异常类可以统一对外异常展示的方式

    2. 有时候处理某些校验或者问题时需要直接结束掉当前请求,可以通过抛出自定义异常来结束。

    3. 可自定义某些符合Java语法但是不符合业务逻辑的“异常”。

    4. 可以隐藏底层的异常,这样更安全,异常信息也更加的直观

    5、Java的异常链

    异常需要封装,但是仅仅封装还是不够的,还需要传递异常。、

    异常链时一种面向对象编程技术,指将捕获的异常包装进一个新的异常中并重新抛出的异常处理方式。原异常被保存为一个新异常的属性(比如说cause)。这样做的意义时一个方法应该抛出定义在相同的抽象层次上的异常,但是不会丢弃更低层次的信息。

    如果需要理解的话,大概是

    1. 方法a需要一个object-b来完成接下来的操作,所以它调用了方法b来生成,

    2. 但是方法b发生了异常b,无法完成操作并返回异常b。

    3. 那么方法a收到异常b,但是没收到object-b,无法完成操作,准备抛出异常a,抛出异常a的时候需要把收到的异常b封装进去一起抛出,不然上层程序无法弄清楚异常到底是为什么发生的。

    或者说看看编程时调用方法出错后跳出的一连串的报错吧。

     

    参考

     

    Java异常类型及处理

    JAVA基础——异常详解

    Java API文档

    当你深入了解,你就会发现世界如此广袤,而你对世界的了解则是如此浅薄,请永远保持谦卑的态度。
  • 相关阅读:
    引入包时“”与<>的区别
    Scanners
    一个SQLite数据库的LIKE查询和IN集合查询的代码实例
    @synchronized线程同步互斥锁
    makeKeyAndVisible
    NSString 数字判断
    UILabel UITextField UITextView
    (转载)JAVA SE6.0 中使用SplashScreen
    转帖(http://hi.baidu.com/johnehuang/blog/item/e1e96782a4b04e97f703a6dc.html)
    ce
  • 原文地址:https://www.cnblogs.com/liwxmyself/p/14827659.html
Copyright © 2020-2023  润新知