JAVA异常

上一篇 / 下一篇  2020-09-03 13:18:25

  异常的处理
  1、抛出异常
  ·显示的 throw 抛出异常
  ·JVM遇到异常状态时,隐式的抛出异常
  2、捕获异常涉及代码块
  ·try代码块:用来标记需要进行异常监控的代码
  ·catch代码块:定义针对 catch() 内的异 常类型的 异常处理器,由于处理异常时至上而下匹配异常表!故catch内的异常类型不可覆盖后边的!支持多异常catch(xx | xx)检测
  ·finally代码块:声明一段必定允许的代码!会定义一个 any的异常处理器 监控try catch整个区域
  异常基本概念
  ·本质:程序控制权的一种即时的,非局部的转换———从异常抛出的地方转换到处理异常的地方
  ·原理:一切异常都是Throwable的子类
  Error为不可捕获的异常unchecked exception
  Exception的子类 RuntimeException为程序虽然无法继续但是还可以抢救一下(不经常发生)的异常unchecked exception, 其他子类均为 必须捕获且处理的异常checked exception。
  checked exception 需要显示地捕获,或者throws 标注,以便最大化利用java编译器的编译时检查
  unchecked exception 虽然不被编译器检测,但会检测 手动抛出的unchecked exception
  ·异常实例的构造代价非常大,因为需要生成栈轨迹等等!
  1、如何捕获异常?
  ·关于异常器:当生成字节码后,每个方法都具备0 或 多个异常处理器,异常表内的每个条目代表一个异常处理器,表格可以表示台条目的顺序, 控制范围, 异常类型等等!(表格顺序是由class文件定义的)使用javap对含有异常的源码进行反编译, 可以查看异常表
  ·捕获过程:当程序触发异常时,JVM会自上而下的遍历搜索异常表内条目,逐一对照1. 是否在其监控范围 2,异常类型是否相同! 如果无匹配条目,java栈出栈恢复到调用方法内,在调用者身上遍历异常表, 如果到了栈低仍无匹配条目,这整个执行线程将被禁止!
  2、finally
  ·finally只可以和 try 配合使用
  ·为什么finally总是可以执行?
  复制finally内语句,放到try-catch语句正常执行路径以及异常执行路径的出口中。
  使用javap -c 反汇编包含finally语句代码 会 看到有三个finlly代码块
  针对异常处理路径可能处理try-catch整个代码块内的任何一个异常,所以java编译器会生成一个或多个any类型的异常处理器用来监控整个try-catch区域,该条目target会指向另一份复制的finally代码块,java编译器会重新抛出所捕获的异常
  ·如果catch有return话,是否执行finally内语句? 执行,但是不影响 return 语句返回的值! java思想 1. 后面的语句不可以影响前面的语句! 2. return 存在就是是方法的最后执行的语句
  3、异常屏蔽?
  ·比如: 就是当 某方法 throws XxxException 后,连续进行 throw XXXException(); 最终该方法只会抛出 最后throw的异常 除非在最后显示throw之前存在隐式throw运行时异常!最终throw该隐式异常!
  ·如果解决前面显示throw的异常被屏蔽呢?
  遇到异常就使用 try-catch 进行抛出!不要继续向上抛!
  使用 addSuppressed(lastException) 将之前的异常信息和新异常合并!
  4、try-with-resource 语法糖
  ·自动进行流的关闭!
  ·程序可以在 try 关键字后声明并实例化实现了 AutoCloseable 接口的类
  try(new xx(); new xx()??{ xxxxx}catch{}finally{}
  ·try-with-resource底层使用addSuppressed()!
  ·反编译:
  就是编译器把苦活给干了!
  源码:
  public class Foo implements AutoCloseable {
  private final String name;
  public Foo(String name) { this.name = name; }
  @Override
  public void close() {
  throw new RuntimeException(name);
  }
  public static void main(String[] args) {
  try (Foo foo0 = new Foo("Foo0");
  Foo foo1 = new Foo("Foo1");
  Foo foo2 = new Foo("Foo2")) { int a = 100;
  }
  }
  }
  反编译文件:
       // Decompiled by DJ v3.12.12.96 Copyright 2011 Atanas Neshkov  Date: 8/10/2020 4:56:47 PM
       // Home Page: http://members.fortunecity.com/neshkov/dj.html  http://www.neshkov.com/dj.html - Check often for new version!
       // Decompiler options: packimports(3) 
       // Source File Name:   Foo.java
       
       
       public class Foo
           implements AutoCloseable
       {
       
           public Foo(String s)
           {
               name = s;
           }
       
           public void close()
           {
               throw new RuntimeException(name);
           }
       
           public static void main(String args[])
           {
               Foo foo = new Foo("Foo0");
               try
               {
                   Foo foo1 = new Foo("Foo1");
                   try
                   {
                       Foo foo2 = new Foo("Foo2");
                       byte byte0;
                       try
                       {
                           byte0 = 100;
                       }
                       catch(Throwable throwable3)
                       {
                           try
                           {
                               foo2.close();
                           }
                           catch(Throwable throwable5)
                           {
                               throwable3.addSuppressed(throwable5);
                           }
                           throw throwable3;
                       }
                       foo2.close();
                   }
                   catch(Throwable throwable1)
                   {
                       try
                       {
                           foo1.close();
                       }
                       catch(Throwable throwable4)
                       {
                           throwable1.addSuppressed(throwable4);
                       }
                       throw throwable1;
                   }
                   foo1.close();
               }
               catch(Throwable throwable)
               {
                   try
                   {
                       foo.close();
                }
                   catch(Throwable throwable2)
                {
                       throwable.addSuppressed(throwable2);
                }
                   throw throwable;
            }
               foo.close();
           }
       
           private final String name;
       }


TAG: 软件开发 Java

 

评分:0

我来说两句

Open Toolbar