0

0

final、finally、finalize 有什么区别?

畫卷琴夢

畫卷琴夢

发布时间:2025-11-23 08:39:05

|

356人浏览过

|

来源于php中文网

原创

final用于声明不可变性,finally用于异常处理后的资源清理,finalize则与垃圾回收相关但不推荐使用。

final、finally、finalize 有什么区别?

简单来说,final用于声明不可变的特性,finally用于处理异常后的清理工作,而finalize则与垃圾回收相关,但通常不推荐使用。

finalfinallyfinalize 的具体使用场景

finalfinallyfinalize 虽然拼写相似,但它们在 Java 中扮演着截然不同的角色。理解它们的差异对于编写健壮、高效的代码至关重要。

final 关键字:不可变性的保障

final 关键字可以用于修饰类、方法和变量,分别赋予它们不同的不可变特性:

  • final 类: 表示该类不能被继承。例如,java.lang.String 就是一个 final 类,这意味着你无法创建 String 的子类来修改其行为。这对于保证类的行为一致性和安全性非常重要。

    final class ImmutableClass {
        // ...
    }
    
    // 尝试继承 ImmutableClass 会导致编译错误
    // class SubClass extends ImmutableClass {}
  • final 方法: 表示该方法不能被子类重写 (override)。这可以防止子类修改父类方法的行为,确保父类方法的逻辑得到保留。

    class ParentClass {
        final void finalMethod() {
            System.out.println("This is a final method.");
        }
    }
    
    class ChildClass extends ParentClass {
        // 尝试重写 finalMethod 会导致编译错误
        // void finalMethod() {}
    }
  • final 变量: 表示该变量的值一旦被初始化后,就不能再被修改。这对于创建常量或确保变量的值在程序运行过程中保持不变非常有用。

    final int CONSTANT_VALUE = 10;
    // CONSTANT_VALUE = 20; // 尝试修改 CONSTANT_VALUE 会导致编译错误
    
    final List list = new ArrayList<>();
    list.add("item1"); // 可以修改 list 的内容
    // list = new LinkedList<>(); // 尝试修改 list 的引用会导致编译错误

    需要注意的是,final 变量只能保证引用不可变,如果 final 变量指向的是一个可变对象(例如 ArrayList),那么仍然可以修改该对象的内容。

finally 块:异常处理的最后一道防线

finally 块用于定义无论 try 块中是否发生异常,都必须执行的代码。它通常用于释放资源、关闭连接或执行其他清理操作,确保程序在发生异常时也能正确地恢复到稳定状态。

try {
    // 可能会抛出异常的代码
    // 例如:打开文件、读取数据
    FileInputStream fis = new FileInputStream("file.txt");
    // ...
} catch (IOException e) {
    // 处理异常
    System.err.println("An IOException occurred: " + e.getMessage());
} finally {
    // 无论是否发生异常,都会执行的代码
    // 例如:关闭文件流
    try {
        if (fis != null) {
            fis.close();
        }
    } catch (IOException e) {
        System.err.println("Error closing file: " + e.getMessage());
    }
}

即使在 try 块中遇到了 return 语句,finally 块中的代码仍然会被执行。这使得 finally 块成为确保资源得到正确释放的关键机制。

Stenography
Stenography

一个AI驱动的代码库API

下载

finalize 方法:垃圾回收的钩子 (不推荐使用)

finalize 方法是 java.lang.Object 类的一个受保护的方法。它的目的是允许对象在被垃圾回收器回收之前执行一些清理操作。然而,finalize 方法存在一些严重的问题,因此通常不推荐使用。

  • 不确定性: 无法保证 finalize 方法何时会被调用。垃圾回收器何时运行是不确定的,因此 finalize 方法的执行时间也是不确定的。
  • 性能问题: 带有 finalize 方法的对象会增加垃圾回收的负担,降低程序的性能。
  • 可能导致对象复活:finalize 方法中,对象可能会重新被引用,导致对象无法被回收,从而引发内存泄漏。

由于这些问题,Java 9 中已经标记 finalize 方法为 deprecated。建议使用其他机制来释放资源,例如 try-with-resources 语句或显式地调用 close() 方法。

class MyClass {
    // 避免使用 finalize 方法
    @Override
    protected void finalize() throws Throwable {
        // 不要在这里释放资源
        // ...
    }
}

为什么不推荐使用 finalize 方法?

finalize 方法的设计初衷是好的,但它在实际使用中存在很多问题,导致它成为一个不可靠且不推荐使用的机制。

  • 资源释放的不确定性: 依赖垃圾回收器来释放资源是不确定的。垃圾回收器何时运行受到很多因素的影响,例如内存使用情况、系统负载等。如果程序依赖 finalize 方法来释放关键资源,可能会导致资源泄漏或程序崩溃。
  • 性能开销: 带有 finalize 方法的对象需要额外的处理,会增加垃圾回收的负担,降低程序的性能。
  • 对象复活:finalize 方法中,对象可以重新被引用,导致对象无法被回收,从而引发内存泄漏。更糟糕的是,对象可能会多次被复活,导致程序行为变得不可预测。
  • 异常处理困难: 如果 finalize 方法抛出异常,垃圾回收器会忽略该异常,导致程序无法正确地处理错误。

替代 finalize 方法的方案

由于 finalize 方法存在诸多问题,建议使用以下替代方案来释放资源:

  • try-with-resources 语句: try-with-resources 语句可以自动关闭实现了 java.lang.AutoCloseable 接口的资源。这是一种简单、安全、可靠的资源管理方式。

    try (FileInputStream fis = new FileInputStream("file.txt")) {
        // 使用 fis 读取数据
        // ...
    } catch (IOException e) {
        // 处理异常
        System.err.println("An IOException occurred: " + e.getMessage());
    }
    // fis 会在 try 块结束后自动关闭
  • 显式地调用 close() 方法: 对于没有实现 AutoCloseable 接口的资源,可以显式地调用 close() 方法来释放资源。

    FileInputStream fis = null;
    try {
        fis = new FileInputStream("file.txt");
        // 使用 fis 读取数据
        // ...
    } catch (IOException e) {
        // 处理异常
        System.err.println("An IOException occurred: " + e.getMessage());
    } finally {
        if (fis != null) {
            try {
                fis.close();
            } catch (IOException e) {
                System.err.println("Error closing file: " + e.getMessage());
            }
        }
    }
  • 使用 PhantomReference 如果需要在对象被垃圾回收时执行一些清理操作,可以使用 PhantomReferencePhantomReference 可以让你知道对象已经被垃圾回收器标记为可回收,但你不能通过 PhantomReference 访问到该对象。

    ReferenceQueue queue = new ReferenceQueue<>();
    PhantomReference phantomRef = new PhantomReference<>(new MyObject(), queue);
    
    // ...
    
    Reference ref = queue.poll();
    if (ref != null) {
        // 对象已经被垃圾回收器标记为可回收
        // 执行清理操作
        // ...
        ref.clear();
    }

总而言之,理解 finalfinallyfinalize区别,并正确地使用它们,可以帮助你编写出更健壮、更高效的 Java 代码。避免使用 finalize 方法,并选择更可靠的资源管理方式,可以有效地避免资源泄漏和性能问题。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

829

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

735

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

733

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

396

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16925

2023.08.03

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

3

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.4万人学习

C# 教程
C# 教程

共94课时 | 6.4万人学习

Java 教程
Java 教程

共578课时 | 44.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号