You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中删除对象使后续访问报错的实现及置null无效的原因解析

Java对象删除问题解答

1. 为什么将f2引用设置为null后,仍然可以访问到原f2对象的data属性

  • Java中的f1、f2、f3都属于引用变量,仅存储堆空间中实际对象的内存地址,和堆中的对象本身是独立的。
  • 初始化f3时传入f2,本质是把f2当时存储的「data为23的bar对象的内存地址」直接赋值给f3.prev属性。此时f2和f3.prev是两个完全独立的引用,只是指向同一个堆对象。
  • 执行f2 = null仅会清空f2这个引用变量本身的值,不会修改f3.prev的指向,也不会直接删除堆中的目标对象。同时由于目标对象仍被f3.prev强引用,属于GC可达对象,垃圾回收器不会回收该对象,因此依然可以正常访问其属性。

2. 要正确删除该对象使得后续访问触发报错,该如何操作

你需要手动清除所有指向待删除对象的强引用,具体操作如下:

  1. 去掉bar类中prev属性的final修饰,允许修改引用指向
  2. 找到所有持有待删除对象引用的位置,将对应引用赋值为null。你当前场景中只有f3.prev持有目标对象的引用,直接修改该属性即可
  3. 如果是完整的双向链表场景,还需要同时修改待删除节点的前驱节点的next指针、后继节点的prev指针,彻底清除所有指向该节点的引用

修改后的可复现报错的代码如下:

public class prog {
    public static void main(String[] args) {
        bar f1 = new bar(12, null);
        bar f2 = new bar(23, f1);
        bar f3 = new bar(42, f2);
        f2 = null;
        // 清空f3持有的原f2对象引用
        f3.prev = null;
        // 调用reveal时会抛出NullPointerException
        f3.reveal();
    }
}

class bar {
    final int data;
    // 移除final修饰,允许修改prev指向
    bar prev;

    bar(int data, bar prev) {
        this.data = data;
        this.prev = prev;
    }

    void reveal() {
        System.out.println("Value of this object is " + this.data);
        System.out.println("Value of Previous object is " + this.prev.data);
    }
}

执行上述代码会触发Exception in thread "main" java.lang.NullPointerException,符合你要的报错效果。

内容的提问来源于stack exchange,提问作者tycoon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 15:57:03