找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1964

积分

0

好友

280

主题
发表于 2025-12-25 17:22:15 | 查看: 30| 回复: 0

finalfinallyfinalize是Java语言中三个看似相似但用途迥异的关键概念,理解它们的区别是Java开发者必须掌握的基础知识,也是技术面试中的常见考点。

final 关键字

final 是一个修饰符关键字,用于声明类、方法或变量,表示它们具有“不可变性”。

  • final 类:该类不能被继承。

    public final class FinalClass {
        // 类内容
    }
    // public class SubClass extends FinalClass { // 编译错误,不能继承 final 类
    // }
  • final 方法:该方法不能被子类重写(Override)。

    public class BaseClass {
        public final void display() {
            System.out.println("This is a final method.");
        }
    }
    
    public class DerivedClass extends BaseClass {
        // public void display() { // 编译错误,不能重写 final 方法
        //     System.out.println("Trying to override.");
        // }
    }
  • final 变量:该变量一旦被初始化赋值,其值就不能再被修改。对于基本类型,值不变;对于引用类型,引用指向的对象地址不变(但对象内部状态可能改变)。

    public class MyClass {
        public static final int MY_CONSTANT = 10; // 常量
        private final List<String> list = new ArrayList<>(); // 引用不可变,但list内容可增删
    }

finally 代码块

finally 是与 try-catch 语句配合使用的代码块,用于放置必须执行的清理代码,无论是否发生异常,finally 块中的代码通常都会执行。

常见的应用场景包括关闭数据库连接、释放文件句柄、确保锁被解锁等。

try {
    // 可能抛出异常的代码
} catch (Exception e) {
    // 异常处理逻辑
} finally {
    // 清理代码,无论是否发生异常都会执行
    // 例如:conn.close();
}

可以使用 try-finallytry-catch-finally 结构。

注意:在几种极端情况下,finally 块可能不会被执行,在涉及并发与资源管理的场景中需要特别注意:

  1. JVM 非正常退出:程序调用 System.exit(int status) 强制终止虚拟机。
    try {
        System.out.println("Try block");
        System.exit(0); // JVM退出,finally不执行
    } finally {
        System.out.println("Finally block"); // 不会打印
    }
  2. 无限循环或死锁trycatch 块中的代码导致线程陷入无限循环或死锁,程序无法正常执行到 finally 块。
  3. 致命错误try 块中发生了 OutOfMemoryError(内存耗尽)等致命错误,导致JVM进程异常终止。
    try {
        List<byte[]> list = new ArrayList<>();
        while (true) {
            list.add(new byte[10 * 1024 * 1024]); // 持续消耗内存,最终OOM
        }
    } finally {
        System.out.println("Finally block"); // OOM后很可能不会执行
    }

finalize 方法

finalize()Object 类中定义的一个受保护方法。设计初衷是让对象在被垃圾回收器回收之前,有机会执行一些资源清理工作(如关闭非JVM管理的原生资源)。

public class MyClass {
    @Override
    protected void finalize() throws Throwable {
        try {
            // 资源清理代码
        } finally {
            super.finalize(); // 调用父类的finalize
        }
    }
}

重要提示finalize() 方法已经过时(deprecated),不推荐使用。原因如下:

  • 执行时机不确定finalize() 的调用依赖于垃圾回收,而垃圾回收的时机是不确定的。
  • 性能开销大:会延长对象的生命周期,可能导致对象经过多次GC周期才能被回收,影响内存回收效率。
  • 可靠性差:不能保证一定被调用(如JVM紧急终止时)。

替代方案:现在推荐使用显式的资源管理方式。

  • try-with-resources 语句:自动关闭实现了 AutoCloseableCloseable 接口的资源。
    // BufferedReader 实现了 AutoCloseable 接口
    try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) {
        String line = br.readLine();
        // 使用资源
    } catch (IOException e) {
        e.printStackTrace();
    }
    // 退出try块后,br会自动调用close()方法
  • 显式调用关闭方法:在 finally 块或利用生命周期回调(如Spring的 @PreDestroy)中手动关闭资源。

总结对比

特性 final finally finalize
性质 关键字(修饰符) 关键字(代码块标识) Object类的方法
作用 修饰类、方法、变量,赋予不可变性 定义异常处理中必须执行的清理代码块 对象被GC前提供清理机会(已过时)
执行时机 编译时/类加载时/初始化时确定 在try/catch块后(几乎)总是执行 垃圾回收时(不确定)



上一篇:COSE跨平台同步工具:基于Markdown的高效内容发布方案
下一篇:GCC编译器优化等级选型指南与实战避坑
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-10 08:51 , Processed in 0.305789 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表