在以下场景中,
import A;
public class B{
static A a;
static{
a = new A();
}
}
在static initialization block
正确初始化之前,a
是否可能被调用?注意:A
这里是一个日志框架。
答案 0 :(得分:4)
如果您提到上面的情况,将在A初始化之前调用静态块,因为在加载类时将调用静态块(在您的情况下为B类)。所以当你这样做时
B.someStaticMethod()
将加载第一个类B,其中使用它调用静态块(在JVM中进行一次处理)然后将调用静态方法。
另请注意,导入语句以加载类不会加载该类。当你在那个班上做一些操作时就会发生这种情况。
答案 1 :(得分: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只是一个日志记录框架,那么它不是任何专有的,你可能会根据特定框架的实际情况获得更有用的答案。
编辑:请参阅下面评论中提供的链接以获取具体示例。
答案 2 :(得分:2)
进口与此无关。在运行时没有导入。
引用的类在链接阶段加载,该阶段在初始化阶段之前。在这种情况下,在B的静态初始化程序执行之前,在B的链接解析步骤中加载A.
答案 3 :(得分:1)
一个类可以有任意数量的静态初始化块,以及它们 可以出现在类体中的任何位置。运行时系统保证 静态初始化块按它们的顺序调用 出现在源代码中。
为了在A正确初始化之前不可能调用静态块。
如果您初始化static
实例(例如
静态A a =新A();
答案 4 :(得分:0)
静态A a; 静态的{ a = new A(); } 这段代码的明确含义是代码 a = new A(); 将被调用并初始化一次,并在加载类时保持永久生成,直到主线程退出系统。