首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >递归初始化:在我访问类字段时不调用静态初始化程序

递归初始化:在我访问类字段时不调用静态初始化程序
EN

Stack Overflow用户
提问于 2015-05-09 16:52:16
回答 1查看 403关注 0票数 3

理解如何加载类和调用静态初始化程序

静态初始化程序块的顺序是什么?

所以,我只是想确认一下-

代码语言:javascript
运行
复制
public class OOMErrorB extends OOMErrorA {
    public static int c = 10;

    static {
        System.out.println("Loading static B " + c);
        System.out.println(OOMErrorA.a);
    }

    public static void main(String[] args) {
        new OOMErrorB();
    }
}

父类是-

代码语言:javascript
运行
复制
public class OOMErrorA {
    public static int a = 20;

    static {
        a = a+ OOMErrorB.c;
        System.out.println("OOMErrorB.c " + OOMErrorB.c);
        System.out.println("loading OOMErrorA.a " + a);
    }
}

现在输出的主要方法是B-

**

代码语言:javascript
运行
复制
OOMErrorB.c 0
loading OOMErrorA.a 20
Loading static B 10
20

**

我可以理解,首先它是加载A类,因为它是超类,并且调用它是静态初始化器,

现在,由于我在OOMErrorA的静态块中访问OOMErrorB.c,所以它应该加载和调用OOMErrorB的静态初始化器。所以,OOMErrorB.c应该是10而不是0。

我知道如何装载和初始化一个类-

代码语言:javascript
运行
复制
1) Class and gets loaded and variables are initialized to default values like for int - 0, Object - null.
2) Class field are initialized to specified values.
3) Static block gets called .

在我的程序中,我可以看到类OOMErrorB被加载(步骤1),但是步骤2和步骤3没有执行。

然而,根据链路上公认的答案,它应该调用OOMErrorB的静态初始化器。

所以它最终应该是循环依赖的?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-09 16:56:53

当访问OOMErrorB.c时,没有加载OOMErrorB,因为它已经在加载过程中(当JVM最初加载它以调用main方法时)。一旦在JVM中加载了一个类,它就不会再加载了。因此,不存在循环依赖关系:获取OOMErrorB的静态成员c,此时仍未初始化该成员。

您可以检查有关类初始化的本节来自Java语言规范

因为Java编程语言是多线程的,所以类或接口的初始化需要仔细的同步,因为其他一些线程可能同时尝试初始化同一个类或接口。还有可能递归地请求类或接口的初始化,作为该类或接口初始化的一部分;例如,A类中的变量初始化器可能会调用不相关的B类的方法,而后者又可能调用A类的方法。Java虚拟机的实现负责通过以下过程处理同步和递归初始化。

JVM有其正确的方法锁定类的初始化,以防止递归初始化。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30142611

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档