java —— 异常中的陷阱(四)

一、使用 finally 正确关闭资源的方式

  finally 块无论程序是否异常总是会被执行,因此常用来关闭物理资源,从而保证资源总能被关闭。

import java.io.*;

public class CloseResource {

//一个函数同时读取两个文件

public void readTwoFile() throws FileNotFoundException, IOException{

    BufferedReader br1 = null;

    BufferedReader br2 = null;

    FileReader fr = null;

    try{

        fr = new FileReader("A.txt"); //1

        br1 = new BufferedReader(fr); 

        int count = br1.read();    //2

        //process code1....

        fr = new FileReader("B.txt"); //3

        br2 = new BufferedReader(fr);

        count = br2.read(); //4

        //process code2

    }finally{

        if(br1 != null){

            try {
                br1.close(); //5
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        if(br2 != null){

             try {
                br2.close(); //6
            } catch (Exception e) {
                e.printStackTrace();
            }
        }   
    }
}

  这样的关闭方式更加安全保证了,使用 finally 块来关闭物理资源,保证关闭操作总是会被执行; 关闭每个资源之前首先保证引用该资源的引用变量不为 null ; 为每个物理资源使用单独 try...catch 块关闭资源,保证关闭资源时引发的异常不会影响其他资源的关闭。

二、finally 与 return

代码1:

public class TestDemo {
    /**
     *     count=5
     *  int i =++count ; 先加1后赋值给i --> 6
     *  int i =count++ ; 先赋值给i再加1 --> 5
     * @return
     */
    public static int test(){
        int count = 5;
        try{
            //有finally块,不会立即 return
            //finally 有return ,这里的return 不执行
            return ++count;
        } finally{
            System.out.println("---finally----"+count);
            return count++;
        }

    }

    public static void main(String args[]) {

        System.out.println(test());
    }
}
    "输出结果:"
    ---finally----6
        6

  当Java 程序执行try 块、catch 块时遇到了return 语句,return 语句会导致该方法立即结束。

  上述代码,系统执行完return 语句之后,并不会立即结束该方法,而是去寻找该异常处理流程中是否包含finally 块,如果没有finally 块,方法终止,返回相应的返回值。如果有finally 块,系统立即开始执行finally 块——只有当finally 块执行完成后,系统才会再次跳回来根据return 语句结束方法。如果finally 块里使用了return 语句来导致方法结束,则finally 块已经结束了方法,系统将不会跳回去执行 try 块、 catch 块里的任何代码。

代码2:

class Test {
    public int test() {
        int x = 1;

        try {
            return ++x;
        } catch (Exception e) {

        } finally {
            ++x;
        }
        return x;
    }

    public static void main(String[] args) {
        Test t = new Test();
        int y = t.test();
        System.out.println(y);
    }
}

  输出结果: 2

如果try语句里有return,那么代码的行为如下:

1.如果有返回值,就把返回值保存到局部变量中

2.执行指令跳到finally语句里执行

3.执行完finally语句后,返回之前保存在局部变量表里的值

  注意:如果你在finally里也用了return语句,比如return ++x。那么y会是3。因为规范规定了,当try和finally里都有return时,会忽略try的return,而使用finally的return。

代码3:

public static int test() {
        int count = 5;
        try {

            throw new NullPointerException("异常报错");
        } finally {
            System.out.println("finally");
            return count;
        }
    }

    public static void main(String args[]) {
        System.out.println(test());
    }

    输出结果:
    finally
        5

  当程序执行 try 块、 catch 块时遇到 throw 语句时, throw 语句会导致该方法立即结束,系统执行 throw 语句时并不会立即抛出异常给方法的调用者,而是去寻找该异常处理流程中是否包含 finally 块。如果没有 finally 块,程序立即抛出异常;如果有 finally 块,系统立即开始执行 finally 块——只有当 finally 块执行完成后,系统才会再次跳回来抛出异常。如果 finally 块里使用 return 语句来结束方法,系统将不会跳回去执行 try 块、 catch 块去抛出异常。

原文地址:https://www.cnblogs.com/SacredOdysseyHD/p/8412536.html

时间: 2024-11-10 16:50:44

java —— 异常中的陷阱(四)的相关文章

Java EE中常用的四个框架

Java EE中常用的四个框架     Struts     Struts是一个基于Sun Java EE平台的MVC框架,主要是采用Servlet和JSP技术来实现的.     Struts框架可分为以下四个主要部分,其中三个就和MVC模式紧密相关:     1.模型 (Model),本质上来说在Struts中Model是一个Action类(这个会在后面详细讨论),开发者通过其实现商业逻辑,同时用户请求通过控制器(Controller)向Action的转发过程是基于由struts-config

【JAVA】Java 异常中e的getMessage()和toString()方法的异同

参考链接 CSDN: Java 异常中e的getMessage()和toString()方法的异同 示例代码1: public class TestInfo { ????private static String str =null; ????public static void main(String[] args) { ????????System.out.println("test exception"); ????????try { ????????????if(str.equ

异常中的陷阱

正确关闭资源的方式 ①使用finally块来关闭物理资源. ②关闭物理资源时,首先保证引用资源的变量不为null ③每个物理资源时都应该使用单独的try-catch块来关闭资源,保证关闭资源时引发的异常不会影响其他资源的关闭. finally的陷阱 System.exit(0); 在try中使用了System.exit(0);语句,将停止当前线程和所有其他当场死亡的线程.catch和finally块都不会被执行.因为线程都立即死亡了,怎么会执行下面的东西呢? 那么当出现System.exit(0

JAVA面试中的陷阱

第一,谈谈final, finally, finalize的区别.最常被问到. 第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)? 第三,Static Nested Class 和 Inner Class的不同,说得越多越好(面试题有的很笼统). 第四,&和&&的区别.这个问得很少. 第五,HashMap和Hashtable的区别.常问. 第六,Collection

使用String获取java异常中的异常内容

因为Exception类是所有异常的父类,所以使用它可以读取到java产生的所有异常:     /**      * @category 获取try-catch中的异常内容      * @param e Exception      * @return  异常内容      */     public static String getException(Exception e) {         ByteArrayOutputStream out = new ByteArrayOutput

[转]java异常中Exception捕获不到的异常

一 概念 众所周知java提供了丰富的异常类,这些异常类之间有严格的集成关系,分类为 父类Throwable Throwable的两个子类Error和Exception Exception的两个子类CheckedException和RuntimeException 二 发现问题 通常捕获异常catch的时候最大catch到Exception这个类就为止了,当然这能够处理大部分的异常情况. 但是值得注意的是,Exception不能捕捉到所有的异常.比如InvocationTargetExcepti

java异常中finally语句块

关于finally语句块 1.finally语句块可以直接和try语句块联用. try....finally... 2.try...catch....finally 也可以. 3.在finally语句块中的代码是一定会执行的. 4.只要在执行finally语句块之前退出JVM,finally语句块就不会执行. public class ExceptionTest08{ public static void main(String[] args) throws Exception{ /* try{

Java异常打印输出中常见方法的分析

Java异常是在Java应用中的警报器,在出现异常的情况下,可以帮助我们程序猿们快速定位问题的类型以及位置.但是一般在我们的项目中,由于经验阅历等多方面的原因,依然有若干的童鞋在代码中没有正确的使用异常打印方法,导致在项目的后台日志中,没有收到日志或者日志信息不完整等情况的发生,这些都给项目埋下了若干隐患.本文将深入分析在异常日志打印过程中的若干情况,并给出若干的使用建议. 1. Java异常Exception的结构分析 我们通常所说的Exception主要是继承于Throwable而来,可以参

java中存在的四种引用

Java开发中存在四种引用,它们分别是: 强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象具有强引用, 那垃圾回收器绝不会回收它.当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题. 软引用(SoftReference)如果一个对象只具有软引用,则内存空间足够, 垃圾回收器就不会回收它:如果内存空间不足了,就会回收这些对象的内存. 只要垃圾回收器没有回收它,该对象就可以被