异常处理办法之一:try/catch

执行顺序

执行顺序
执行顺序
  • 遇到异常,跳出try,执行catch里面的语句
  • 不管是否遇到异常,finally里面的代码都会被执行,但是后面的就不会。

    try介绍

    异常如何被抛出

    package cn.haien.trycatch;
    import java.io.*;
    /**

    • 关于FileInputStream的try/catch测试
    • @author 14103
      /
      public class TryCatch03 {
      public static void main(String[] args) {
      String str = new TryCatch03().openFile();
      System.out.println(str);
      
      }
      String openFile() {
      try {
          System.out.println("aaa");
          //创建文件字节读取流对象fis
          FileInputStream fis = new FileInputStream("D:\\test.txt");//将字符串路径封装成File对象
          int a = fis.read();//返回读取到的字节
          System.out.println("bbb");
          System.out.println(a);
          return "step1";
      }catch(FileNotFoundException e) {
          e.printStackTrace();
          System.out.println("catch!!!");
          return "step2";
      }catch(IOException e) {
          e.printStackTrace();
          return "step3";
      }finally {  //这里忽略关闭文件操作
          System.out.println("finally1!!");
          //return "fff";  //如果这里加入return,那么返回值一定是fff了,因为会覆盖前面的返回值
          }
      /*总结:执行顺序
      
      执行try、catch语句,给返回值赋值
      执行finally
      return*/
      }
      }

      异常处理办法之二:声明异常——throws

      作用

      谁调我往谁抛出,就谁来处理

      手动抛出

      可以在try里面自己new一个异常对象然后抛出,称为手动抛出,用得不多

try-with-resource及其异常抑制

背景

  • 在Java编程中,如果打开了外部资源(文件、数据库连接、网络连接等),必须在使用完毕后关闭。因为外部资源不由JVM管理,无法享用JVM垃圾回收机制,如果我们不在编程时确保关闭外部资源,就会导致外部资源泄露,紧接着就会出现文件被异常占用、数据库连接过多导致数据池溢出等严重问题。

    传统的资源关闭方式

  • 通常关闭代码被写入finally代码块中,当然我们还必须注意到关闭代码时可能抛出的异常。

    public static void main(String[] args) {
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(new File("test"));
            System.out.println(inputStream.read());
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage(), e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e.getMessage(), e);
                }
            }
        }
    }
    

    JDK7及以后的try-with-resource资源关闭方式

  • 当一个外部资源的句柄对象(比如FileInputStream对象)实现了AutoCloseable接口,那么上述代码就可以简化为如下形式:

    public static void main(String[] args) {
        try (FileInputStream inputStream = new FileInputStream(new File("test"))) {
            System.out.println(inputStream.read());
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    
  • 将外部资源的句柄对象的创建挡在try关键字的括号之中,当这个try/catch代码块执行完毕后,Java会确保外部资源的close方法被调用。代码简介许多。

    实现原理

  • try-with-resouce并不是JVM的新增功能,而是JDK实现的一个语法糖。将以上代码反编译后如下:

    public static void main(String[] args) {
        try {
            FileInputStream inputStream = new FileInputStream(new File("test"));
            Throwable var2 = null; //定义一个即将抛出的异常
    
            try {
                System.out.println(inputStream.read());
            } catch (Throwable var12) { //对资源进行处理(读或写)时遭遇异常
                var2 = var12; //获取这个异常
                throw var12; //并抛出
            } finally {
                if (inputStream != null) {
                    if (var2 != null) { //如果前面抛出了异常
                        try {
                            inputStream.close();
                        } catch (Throwable var11) {
                            var2.addSuppressed(var11); //则将关闭时遭遇的异常信息添加到前面的异常,控制台只打印处理异常,但通过异常的getSupperssed方法,可以提取出被抑制的关闭异常
                        }
                    } else {
                        inputStream.close(); //如果前面无异常,那么关闭异常将被抑制
                    }
                }
    
            }
    
        } catch (IOException var14) {
            throw new RuntimeException(var14.getMessage(), var14);
        }
    }