异常

作者: 小船儿爱学习 | 来源:发表于2020-11-21 12:47 被阅读0次

    异常类

    异常分为受检异常(checked exception)和非受检异常(unchecked exception),也称为编译时异常(unruntime exception)和运行时异常(runtime exception)。
    受检异常/编译时异常:在编译时被强制检查的异常称为"受检查的异常", 即在方法的声明中声明的异常。对可容错处理的情况使用受检异常。
    非受检异常/运行时异常:在方法的声明中没有声明,但在方法的运行过程中发生的各种异常被称为"不被检查的异常"。这种异常是错误,会被自动捕获。对编程错误使用运行时异常。

    异常类的层次结构.jpg

    异常处理

    在程序运行发生异常时,捕获异常并处理或抛弃异常,使程序继续正常运行。
    try-catch-finally:try语句块不能单独使用,必须和catch或finally子句配合使用。当有多个catch子句时,最多只会执行其中一个catch语句块中的异常处理代码,若处理的多个异常之间存在继承关系,则应先处理其子类异常,即处理子类异常的catch子句要放在前面,否则编译不通过。

    参考:https://www.cnblogs.com/cjeandailynotes/p/10565597.html
    结论:
    1、不管有没有出现异常,finally块中代码都会执行。
    2、当try和catch中有return时,finally仍然会执行。finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,不管finally中的代码怎么样,返回的值都不会改变,仍然是之前保存的值),所以函数返回值是在finally执行前确定的。
    3、finally中最好不要包含return,否则程序会提前退出,导致最终的返回值不是try或catch中保存的返回值。

    举例:
    情况1:try{} catch(){} finally{} return;
    显然程序按顺序执行。

    情况2:try{ return; } catch(){} finally{} return;
    程序先执行try块中return之前的代码(包括return语句中的表达式运算);
    再执行finally块,最后执行try中return;
    finally块之后的语句return,因为程序在try中已经return所以不再执行。

    情况3:try{ } catch(){return;} finally{} return;
    程序先执行try,如果遇到异常执行catch块,
    有异常:则执行catch中return之前的代码(包括return语句中的表达式运算),再执行finally语句中全部代码,
    最后执行catch块中return,finally之后的代码不再执行。
    无异常:执行完try再finally再return.

    情况4:try{ return; } catch(){} finally{return;}
    程序执行try块中return之前的代码(包括return语句中的表达式运算);
    再执行finally块,因为finally块中有return所以提前退出。

    情况5:try{} catch(){return;} finally{return;}
    程序执行catch块中return之前的代码(包括return语句中的表达式运算);
    再执行finally块,因为finally块中有return所以提前退出。

    情况6:try{ return;} catch(){return;} finally{return;}
    程序执行try块中return之前的代码(包括return语句中的表达式运算);
    有异常:执行catch块中return之前(包括return语句中的表达式运算)代码;
    则再执行finally块,因为finally块中有return所以提前退出。
    无异常:则再执行finally块,因为finally块中有return所以提前退出。

    最终结论:任何执行try或者catch中的return语句之前,如果finally存在的话,都会先执行finally语句。如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的。
    编译器把finally中的return实现为一个warning。

    // 测试程序
    public class FinallyTest {
      public static void main(String[] args) {
           System.out.println(new FinallyTest().test());
       }
       static int test() {
           int x = 1;
           try {
               x++;
               return x;
           } finally {
               ++x;
           }
       }
    }
    

    运行结果是2。
    在try语句中,在执行return语句时,要返回的结果已经准备好了,就在此时,程序转到finally执行了。
    在转去之前,try中先把要返回的结果存放到不同于x的局部变量中去,执行完finally之后,在从中取出返回结果,因此,即使finally中对变量x进行了改变,但是不会影响返回结果。
    它应该使用栈保存返回值。

    自定义异常
    自定义异常来处理特殊的情况。
    自定义异常类一般都以Exception类为父类。
    自定义异常类对象只能用throw语句抛出。

    敏感异常列表

    异常名称 信息泄露/威胁描述
    java.io.FileNotFoundException 泄露文件系统结构和文件名列举
    java.util.jar.JarException 泄露文件系统结构
    java.util.MissingResourceException 资源列举
    java.security.acl.NotOwnerException 所有人列举
    java.util.ConcurrentModificationException 可能提供线下不安全的代码信息
    javax.naming.InsufficientResourcesException 服务器资源不足(可能有利于DoS攻击)
    java.net.BindException 当不信任客户端能够选择服务器端口时造成开放端口列举
    java.lang.OutOfMemoryError DoS
    java.lang.StackOverflowError DoS
    java.sql.SQLException 数据库结构,用户名列举

    运行时异常列表

    异常名称 描述
    java.lang.ArithmeticException 算数异常
    java.lang.ArrayIndexOutOfBoundsException 数组下标越界异常
    java.lang.ClassCastException 类转换异常
    java.lang.ClassNotFoundException 指定的类不存在异常
    java.io.IOException 输入输出异常
    java.lang.IllegalArgumentException 方法参数异常
    java.lang.IllegalAccessException 无访问权限异常
    java.lang.IndexOutOfBoundsException 下标越界异常
    java.lang.NullPointerException 空指针异常
    java.lang.NoSuchMethodError 方法不存在异常
    java.lang.NumberFormatException 数字格式异常
    java.sql.SQLException sql语句执行异常

    相关文章

      网友评论

          本文标题:异常

          本文链接:https://www.haomeiwen.com/subject/ayfriktx.html