何时导入的类在java中加载?

时间:2013-05-02 04:31:30

标签: java classloader

在以下场景中,

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

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

5 个答案:

答案 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.

参考:JVM Specification: Loading, Linking, and Initializing

答案 3 :(得分:1)

  

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

Documentation

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

如果您初始化static实例(例如

),我认为不会有任何混淆
  

静态A a =新A();

答案 4 :(得分:0)

静态A a;     静态的{         a = new A();     } 这段代码的明确含义是代码 a = new A(); 将被调用并初始化一次,并在加载类时保持永久生成,直到主线程退出系统。