4

在以下场景中,

import A;
public class B{
    static A a;
    static{
        a = new A();
    }
}

static initialization block之前调用的gets是否有可能a被正确初始化?注意:A这里是一个日志框架。

4

5 回答 5

4

在上面提到的情况下,将在初始化 A 之前调用静态块,因为在类加载时将调用静态块(在您的情况下为 B 类)。所以当你这样做时

B.someStaticMethod() 

第一个类 B 将在调用静态块的地方加载(JVM 中的一次处理),然后调用静态方法。

另请注意,加载类的导入语句不会加载类。当你对该类进行一些操作时会发生这种情况。

于 2013-05-02T04:35:35.937 回答
3

进口与它无关。运行时没有导入。

引用的类在初始化阶段之前的链接阶段加载。在这种情况下,在 B 的静态初始化程序执行之前,在 B 的链接解析步骤期间加载 A。

参考:JVM 规范:加载、链接和初始化

于 2013-05-02T04:54:08.297 回答
2

首先,有可能,但不确定,静态初始化程序会在 A “正确初始化”之前被调用。静态初始化程序将在类加载器加载 B 时执行(参见 #9:http ://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.2 )。我们没有从您提供的信息中获得足够的信息,无法知道相对于正在加载的 A 何时会发生这种情况(B 的静态初始化程序中的构造函数调用可能是第一次加载 A,或者它可能在很久以前就发生了)。

其次,一个正在初始化的 A 的实例很可能会触发 A 的初始化,这样一切都会自行解决。请记住,A 的构造函数在加载类之前不会执行,这将包括为 A 运行任何静态初始化程序。所以我不确定您担心哪种类型的初始化可能不会发生。

第三,import 语句与此无关。无论您完全限定 com.foo.A 是否使用 import 语句,它的行为都会相同。

最后,如果您提供一个真实的例子,它可能会有所帮助。如果 A 只是一个日志框架,那么它不是任何专有的,您可能会根据该特定框架的实际情况得到更有用的答案。

编辑:请参阅下面评论中提供的链接以获取具体示例。

于 2013-05-02T04:47:27.417 回答
1

一个类可以有任意数量的静态初始化块,它们可以出现在类主体的任何位置。运行时系统保证静态初始化块按照它们在源代码中出现的顺序被调用。

文档

为此,不可能在 A 正确初始化之前调用静态块。

static我认为如果你初始化你的实例不会有混淆-

静态 A a = 新 A();

于 2013-05-02T04:37:28.210 回答
0

静态的一个;静态{ a = new A(); 这段代码清楚的意思是代码 a = new A(); 将只被调用和初始化一次,并在加载类直到主线程退出系统时保持在永久代中。

于 2013-05-02T05:02:46.253 回答