当前位置: 首页 > article >正文

Java基础面试题07:finalize() 方法什么时候被调用?析构函数(finalization)的目的是什么?

Java 提供了一个 finalize() 方法,允许在垃圾回收器将对象从内存中清除之前,对对象进行必要的清理工作。以下内容将对 finalize() 的调用时机、析构函数的目的以及 finalfinalize 的区别进行深入解析。


finalize() 方法

finalize() 是 Java 的一个特殊方法,它属于所有类的“祖宗”——Object 类,也就是说每个 Java 类都默认继承了这个方法。它的核心作用是:在垃圾回收器回收对象之前进行清理操作

finalize() 方法什么时候被调用?

  • 调用时机
    当垃圾回收器发现某个对象已经没有任何引用时,它会对该对象调用 finalize() 方法,进行必要的清理操作。

  • 调用过程

    1. 假设有一个对象 Dog,它占用了一块堆内存。对象的引用用变量 d 表示:

      Dog d = new Dog();
      
    2. 当我们将 d 赋值为 null 时:

      d = null;
      

      这意味着程序中已经没有任何地方可以访问到这个 Dog 对象,它变成了“无主对象”。

    3. 此时,垃圾回收器会将这个对象标记为“可回收”。在实际回收之前,垃圾回收器会自动调用对象的 finalize() 方法。

  • 注意:垃圾回收器并不会立即回收对象,也就是说,赋值为 null 并不等于立刻触发 finalize()。垃圾回收的时间是由 JVM 决定的。


析构函数(finalization) 的目的

析构函数的主要目标是:在对象被销毁之前完成清理工作。这种清理可能包括:

  • 释放资源:比如关闭文件流、数据库连接等。
  • 释放内存:回收程序中动态分配的资源,减少内存泄漏的风险。

举例说明:垃圾回收的过程

让我们看看一个例子来感受 finalize() 的执行:

public class Dog {
    @Override
    protected void finalize() throws Throwable {
        System.out.println("Dog对象即将被垃圾回收!");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog d = new Dog();
        d = null; // 去掉引用
        System.gc(); // 手动触发垃圾回收
        System.out.println("垃圾回收器已经被调用。");
    }
}

运行结果

  1. 调用 System.gc() 后,垃圾回收器被唤醒。
  2. 输出内容:
    垃圾回收器已经被调用。
    Dog对象即将被垃圾回收!
    

这说明垃圾回收器触发了 finalize() 方法,但程序不会等待 finalize() 执行完成后才继续。


final 和 finalize 的区别

两者名字相似,但功能完全不同:

  • final

    1. 修饰类:类不能被继承。
    2. 修饰方法:方法不能被重写。
    3. 修饰变量:变量一旦赋值,不能再改变。
  • finalize
    这是一个方法,用于对象销毁前的资源释放。可以通过重写 finalize() 方法,定义对象被回收时的自定义逻辑。


常见问题解析

Q1:为什么 finalize() 默认没有代码?

Object 类中的 finalize() 方法默认是空实现,因为不是所有对象都需要自定义销毁逻辑。

Q2:为什么手动调用垃圾回收器才看到 finalize() 调用?

垃圾回收器的执行时机由 JVM 决定,System.gc() 只是一种“建议”垃圾回收器运行的方法,并不能保证立即回收对象。

Q3:实际开发中是否经常用 finalize()

很少finalize() 更像是垃圾回收机制的补充,而不是主流解决方案。现代开发中,通常使用更可靠的工具如 try-with-resources 或手动释放资源代替。


总结

  1. finalize() 的作用:清理即将被销毁的对象,释放资源。
  2. 调用时机:当垃圾回收器发现对象无引用且准备回收时。
  3. finalfinalize 的区别:前者用于修饰类、方法和变量,后者是对象销毁前的“善后”方法。
  4. 开发建议:除非有明确需求,否则尽量避免重写 finalize() 方法,优先考虑更现代的资源管理方式。

用一句话记住:finalize() 是对象离开堆内存的告别礼,但不是每次离别都需要繁琐的仪式!

最后说一句(求关注,求赞,别白嫖我)

最近无意间获得一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。
这是大佬写的
7701页的BAT大佬写的刷题笔记,让我offer拿到手软

本文,已收录于,我的技术网站 cxykk.com:程序员编程资料站,有大厂完整面经,工作技术,架构师成长之路,等经验分享

求一键三连:点赞、分享、收藏

点赞对我真的非常重要!在线求赞,加个关注我会非常感激!


http://www.kler.cn/a/414697.html

相关文章:

  • PyCharm中Python项目打包并运行到服务器的简明指南
  • 【论文阅读】Federated learning backdoor attack detection with persistence diagram
  • 全新AI模型家族登场:完全可复现的开源语言模型OLMo 2
  • C语言——指针初阶(一)
  • PMP好考吗,有多大的价值?
  • <项目代码>YOLOv8 停车场空位识别<目标检测>
  • 【unity】WebSocket 与 EventSource 的区别
  • 状态模式S
  • 0.查找命令
  • 【docker 拉取镜像超时问题】
  • NeurIPS 2024 数据集汇总|覆盖云层去除/化学光谱/歌声音频/自动驾驶/昆虫标本······...
  • AI 声音:数字音频、语音识别、TTS 简介与使用示例
  • 爬虫开发(5)如何写一个CSDN热门榜爬虫小程序
  • 学习日志 --A5rZ
  • git:下载与安装
  • HTTPS的安全性优势
  • Pytorch中反向传播
  • C++初阶(十六)--STL--list的模拟实现
  • QT QFormLayout控件 全面详解
  • C++中的volatile关键字
  • torch.set_printoptions
  • 房屋出租出售预约系统支持微信小程序+H5+APP
  • 【含开题报告+文档+PPT+源码】基于SpringBoot的艺术培训学校管理系统的设计与实现
  • vue2 中使用 Ag-grid-enterprise 企业版
  • 解决数据传送问题:内网http传输
  • LeetCode 力扣 热题 100道(十)回文链表(C++)