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

Java对象何时创建?从GC视角及构造器异常场景解析

从GC视角看Java对象的创建时机

我真不敢相信居然没人问过这个问题,它听起来非常基础,但我在Stack Overflow上搜索后没找到相关问题(不是那个讨论构造器调用顺序的问题)。

核心问题:从GC的视角来看,Java中的对象何时被创建?

起初我没多想,认为“至少不会早于构造器执行完毕”。后来我发现Mockito使用一些底层原生技术完全绕过构造器。

之后我了解到finalizer相关的安全问题,验证并确认了以下代码:

public class FinalizerAttackExample {
    public static void main(String[] args) throws InterruptedException {
      try {
          new MaliciousSubclass();
      } catch(SecurityException ex) {
          System.out.println("wouldn't get hands on a ResourceClass instance");
      }
      System.gc();
      Thread.sleep(2000);
    }

    static class ResourceClass {
        ResourceClass() {
            if(!checkCaller()) throw new SecurityException();
        }
        public void criticalAction() {
            System.out.println("ResourceClass.criticalAction()");
        }
    }

    /** For our demonstration, all callers are invalid */
    static boolean checkCaller() {
        return false;
    }

    static class MaliciousSubclass extends ResourceClass {
        @Override
        protected void finalize() {
            System.out.println("see, I got hands on " + this);
            criticalAction();
        }
    }
}

确实会产生如下输出(哈希值可能不同):

wouldn't get hands on a ResourceClass instance
see, I got hands on FinalizerAttackExample$MaliciousSubclass@7ad74083
ResourceClass.criticalAction()

这就引出了问题:如果构造器从未成功执行,那么finalize()是在哪个对象上调用的?Java对象是在构造器的虚拟“finally”块中创建的吗?还是在此之前?

以下是Java语言规范中的描述:

A new class instance is explicitly created when evaluation of a class instance creation expression (§15.9) causes a class to be instantiated.
——JLS, §12.5

这个描述完全没有解决我的疑问。

如果这是JVM相关的(本不应如此),假设我们在Hotspot上运行代码。

内容的提问来源于Stack Exchange,提问作者Sergey Zolotarev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:14:53