Java的finally

在Java中,finally 关键字用于创建一个代码块,它跟在一个try块之后,可选地跟在一个或多个catch块之后。无论try块内发生什么情况(是否发生异常),finally 块中的代码几乎总是会被执行。finally块通常用于清理资源,比如关闭文件、释放内存等,以确保这些代码无论正常逻辑还是异常处理都能得到执行。

这里有finally的一些关键点:

  1. 正常执行:如果try块成功完成,没有异常发生,那么finally块将在try块之后执行。
  2. 异常处理:如果try块中发生异常,并且相应的catch块匹配了这个异常并处理了它,那么finally块将在catch块之后执行。
  3. 无匹配的异常:即使try块中的异常没有被任何catch块捕获(即没有匹配的catch块),finally块仍然会执行。
  4. 未处理的异常:如果try块或catch块中抛出了一个未被捕获的异常,finally块会在异常传播到更高层之前执行。
  5. try/catch块中的return语句:即使trycatch块中有return语句,finally块也会在方法返回之前执行。但是,如果finally块中也有return语句,它将会覆盖trycatch块中的返回值。
  6. try块中的System.exit():如果trycatch块调用System.exit(),那么JVM将会立即终止,finally块不会执行。
  7. finally块中的异常:如果finally块中发生异常,且trycatch块中也有异常发生,那么finally块中的异常将会“覆盖”之前的异常,导致之前的异常丢失。

下面是一个简单的例子,演示finally块的基本用法:

public class FinallyDemo {
    public static void main(String[] args) {
        try {
            int data = 25 / 5;
            System.out.println(data);
        } catch (ArithmeticException e) {
            System.out.println(e);
        } finally {
            System.out.println("finally block is always executed");
        }

        System.out.println("Rest of the code...");
    }
}

在这个例子中,finally块将在try块成功执行之后执行。即使没有异常被抛出,finally块中的语句"finally block is always executed"也会被打印出来。

如果你将25 / 5替换为25 / 0,将会发生ArithmeticExceptioncatch块将会捕获并处理它,但是之后finally块仍然会执行。

finally块是确保资源被适当清理的重要机制,比如关闭文件流或数据库连接,即使在异常情况下也可以保证这些操作被执行。




 

几个不同情景中使用finally`语句的Java代码示例:

示例 1: 确保关闭资源

import java.io.*;

public class FinallyExample {
    public static void main(String[] args) {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader("input.txt"));
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (br != null) br.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}

在这个示例中,无论是否发生IOExceptionfinally块都保证了BufferedReader资源在使用后被关闭。

示例 2: try/catch/finally结合return

public class FinallyReturnExample {
    public static int myMethod() {
        try {
            // This will cause a divide by zero exception
            int result = 25 / 0;
            return result;
        } catch (ArithmeticException e) {
            System.out.println("ArithmeticException caught");
            return -1;
        } finally {
            System.out.println("finally block executed");
            // Return in a finally block will override any previous return
            // But it's a bad practice to do so.
            // return 0;
        }
    }
    
    public static void main(String[] args) {
        int value = myMethod();
        System.out.println("Returned value: " + value);
    }
}

在这个例子中,尽管catch块捕获了异常并返回了-1finally块依然会被执行。如果取消注释finally块中的return 0;,那么这个值将会覆盖catch块中的返回值。

示例 3: finally块中抛出异常

public class FinallyExceptionExample {
    public static void myMethod() {
        try {
            throw new Exception("An error occurred");
        } catch (Exception e) {
            System.out.println("Error caught: " + e.getMessage());
            throw e; // Re-throwing the exception
        } finally {
            System.out.println("finally block executed");
            // Throwing an exception here would cause the previous thrown exception to be lost
            // throw new RuntimeException("Exception from finally");
        }
    }
    
    public static void main(String[] args) {
        try {
            myMethod();
        } catch (Exception e) {
            System.out.println("Caught in main: " + e.getMessage());
        }
    }
}

在这个示例中,finally块在异常被catch块捕获并处理之后执行。如果取消注释finally块中的throw new RuntimeException("Exception from finally");,这个新抛出的异常将会覆盖之前由try块抛出的异常。

示例 4: 在finally块中释放锁

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class FinallyLockExample {
    private static final Lock lock = new ReentrantLock();

    public static void main(String[] args) {
        lock.lock();
        try {
            // Critical section protected by the lock
            System.out.println("Inside the critical section");
        } finally {
            lock.unlock(); // Ensure the lock is released regardless of what happens in the try block
        }
    }
}

在这个示例中,finally块确保了无论在临界区代码执行期间发生什么情况,锁lock最终都会被释放。

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值