Java工程师知识树

Java基础-异常-异常处理关键字

2021-01-15  本文已影响0人  HughJin

Java工程师知识树 / Java基础


异常处理关键字

Java异常处理机制用到的几个关键字:try、catch、finally、throw、throws。

final、finally、finalize的区别与用法

final:用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally:是异常处理语句结构的一部分,表示总是执行。
finalize:是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,供垃圾收集时的其他资源回收,例如关闭文件等。

Try-with-resources

环境

Java1.7版本及其以后版本

语法

JDK1.7开始,java引入了 try-with-resources 声明,将 try-catch-finally 简化为 try-catch,这其实是一种语法糖,在编译时会进行转化为 try-catch-finally 语句。
新的声明包含三部分:try-with-resources 声明try 块catch 块。它要求在 try-with-resources 声明中定义的变量实现了 AutoCloseable 接口,这样在系统可以自动调用它们的close方法,从而替代了finally中关闭资源的功能。

所有实现了 java.lang.AutoCloseable接口(其中,它包括实现了java.io.Closeable 的所有对象),可以使用作为资源。

try-with-resources 声明在 JDK 9 得到改进。如果你已经有一个资源是 final 或等效于 final 变量,您可以在try-with-resources语句中使用该变量,而无需在try-with-resources语句中声明一个新变量。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
 
public class Tester {
   public static void main(String[] args) throws IOException {
      System.out.println(readData("test"));
   } 
   static String readData(String message) throws IOException {
      Reader inputString = new StringReader(message);
      BufferedReader br = new BufferedReader(inputString);
      try (br) {//在 Java 9 中,不需要声明资源 br就可以使用它,并得到相同的结果。
         return br.readLine();
      }
   }
}

作用

关闭在try-catch语句块中使用的资源,需要在ry-with-resources 声明中的实现AutoCloseable 接口的资源。

使用范例

Java1.7之前写法

public static void main(String[] args) {
    FileInputStream file = null;
    try {
        file = new FileInputStream("D:\\logs\\log-cleaner.log");
        System.out.println("ooo");
        file.read();
        System.out.println("aaa");
    } catch (IOException io) {
        System.out.println("bbb");
        io.printStackTrace();
    } catch (Exception e) {
        System.out.println("ccc");
        e.printStackTrace();
    } finally {
        if (file != null) {
            try {
                file.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

使用JDK1.9之前的 try-with-resources异常处理机制

public static void main(String[] args) {
    try(FileInputStream file = new FileInputStream("D:\\logs\\log-cleaner.log")){
        System.out.println("ooo");
        file.read();
        System.out.println("aaa");
    }catch (IOException io){
        System.out.println("bbb");
        io.printStackTrace();
    }catch (Exception e){
        System.out.println("ccc");
        e.printStackTrace();
    }
}

编译后的class文件

public static void main(String[] paramArrayOfString)
{
    try
    {
        FileInputStream localFileInputStream = new FileInputStream("D:\\logs\\log-cleaner.log"); 
        Object localObject1 = null;
        try { 
            System.out.println("ooo");
            localFileInputStream.read();
            System.out.println("aaa");
        }
        catch (Throwable localThrowable2)
        {
            localObject1 = localThrowable2; throw localThrowable2;
        }
        finally
        {
            if (localFileInputStream != null) if (localObject1 != null) try { localFileInputStream.close(); } catch (Throwable localThrowable3) { localObject1.addSuppressed(localThrowable3); } else localFileInputStream.close();
        }
    } catch (IOException localIOException) {
        System.out.println("bbb");
        localIOException.printStackTrace();
    } catch (Exception localException) {
        System.out.println("ccc");
        localException.printStackTrace();
    }
}

return与finally的执行顺序

public class TestException {


    public static void main(String[] args) {
        System.out.println("-------------");
        System.out.println(div());//try中有return,且try中不抛异常。
        /*结果:
        process try
        process finally
        0
         */
        System.out.println("-------------");
        System.out.println(divE());//catch中有return,且try中抛异常。
        /*结果:
        process try
        process catch
        process finally
        2
         */
        System.out.println("-------------");
        System.out.println(divEr());//catch,finally中都有return,且try中抛异常。
        /*
        process try
        process catch
        process finally
        3
         */
    }
    public static int div() {
        int result = 0;
        try {
            System.out.println("process try");
            return result;//如果try和catch的return是一个变量时且函数的是从其中一个返回时,后面finally中语句即使有对返回的变量进行赋值的操作时,也不会影响返回的值。
        } catch (ArithmeticException e) {
            result = 2;
            System.out.println("process catch");//
        } finally {
            result = 3;//finally中语句对返回的变量进行赋值的操作时,也不会影响返回的值
            System.out.println("process finally");//
        }
        return result;
    }
    public static int divE() {
        int result = 0;
        try {
            System.out.println("process try");
            int proces = 1/0;
            return result;
        } catch (ArithmeticException e) {
            result = 2;
            System.out.println("process catch");
            return result;//如果try和catch的return是一个变量时且函数的是从其中一个返回时,后面finally中语句即使有对返回的变量进行赋值的操作时,也不会影响返回的值。
        } finally {
            result = 3;//finally中语句对返回的变量进行赋值的操作时,也不会影响返回的值
            System.out.println("process finally");
        }
    }

    public static int divEr() {
        int result = 0;
        try {
            System.out.println("process try");
            result = 1/0;
            return result;
        } catch (ArithmeticException e) {
            result = 2;
            System.out.println("process catch");
//            throw new ArithmeticException("divEr执行异常");// finally 里有return,这里throw失效
            return result;// finally 里有return,这里return失效
        } finally {
            result = 3;
            System.out.println("process finally");
            return result;//finally块中的return语句会阻止异常的栈调用传输,使divEr认为该方法已经正常返回
        }
    }

}

通过上面代码可以得出结论:

原因通过反编译插件查看Class文件:

上一篇 下一篇

猜你喜欢

热点阅读