未经初始化不执行静态块
Static block not executed without initialization
我有一个关于静态块的问题:
假设我有一个 class 看起来像这样:
class SomeClass {
static {
System.out.println("static block");
}
}
然后我在某处定义了一个 SomeClass
类型的变量。
public static void main(String args[]) {
SomeClass foo;
}
现在我以为静态块会被执行,但事实并非如此。据我所知,一旦 classloader 加载 SomeClass
class,就会执行静态块。现在回答我真正的问题:
class不是一定义那个类型的变量就加载了吗?。如果是,为什么不执行静态块?
如果答案是否定的,那么我如何知道 class 是否已经被 class 加载程序加载以及 class 有哪些不同的可能性已加载(我知道 2:初始化变量并使用静态 field/method)
参考这个文档:http://www.javaworld.com/article/2077260/learn-java/learn-java-the-basics-of-java-class-loaders.html
So when are classes loaded? There are exactly two cases: when the new bytecode is executed (for example, FooClass f = new FooClass();) and when the bytecodes make a static reference to a class (for example, System.out).
在您的示例中,SomeClass foo;
既不执行 SomeClass 的字节码,也不对 SomeClass 进行静态引用。这就是 class 未加载的原因。
因此,按照您的示例,在 class
中添加一个静态字段
public class SomeClass {
static {
System.out.println("static block");
}
static String abc = "abc";
}
SomeClass 被加载到:
SomeClass foo = new SomeClass();
或
System.out.println(SomeClass.abc);
Isn't the class loaded as soon as I define a variable of that type?.
是的,它被加载1,但是它不会因为声明一个变量而被初始化。但是,当您创建该类型的实例或访问该类型的静态字段时,这足以触发初始化,包括静态块的执行。
查看此相关问答 - When does static class initialization happen? - 其中列出了可以触发初始化的所有内容。
How can i know if a class has already been loaded by the class loader and what are the different possibilities to have the class loaded (I know of 2: initializing the variable & using a static field/method)
我能想到的找出 class 何时加载(与初始化不同)的唯一方法是:
打开 JVM 的 class 加载程序消息(使用 -verbose:class
),或
使用客户 classloader 注意到,并在看到加载 class.
的请求时做一些适当的事情
一个class实际上要被加载:
当使用 Class.forName
或类似方式显式加载时,或直接调用 classloader,
为了link另一个class或
需要加载它时
在 JVM 启动时,如果 class 被命名为入口点 class。
加载/linking/初始化步骤在Chapter 12 of the JLS中指定。
1 - 事实上,SomeClass
需要在包含 main
方法的 class 是 [ 的同时加载=74=]ed;即在调用包含该局部声明的方法之前。
我有一个关于静态块的问题:
假设我有一个 class 看起来像这样:
class SomeClass {
static {
System.out.println("static block");
}
}
然后我在某处定义了一个 SomeClass
类型的变量。
public static void main(String args[]) {
SomeClass foo;
}
现在我以为静态块会被执行,但事实并非如此。据我所知,一旦 classloader 加载 SomeClass
class,就会执行静态块。现在回答我真正的问题:
class不是一定义那个类型的变量就加载了吗?。如果是,为什么不执行静态块?
如果答案是否定的,那么我如何知道 class 是否已经被 class 加载程序加载以及 class 有哪些不同的可能性已加载(我知道 2:初始化变量并使用静态 field/method)
参考这个文档:http://www.javaworld.com/article/2077260/learn-java/learn-java-the-basics-of-java-class-loaders.html
So when are classes loaded? There are exactly two cases: when the new bytecode is executed (for example, FooClass f = new FooClass();) and when the bytecodes make a static reference to a class (for example, System.out).
在您的示例中,SomeClass foo;
既不执行 SomeClass 的字节码,也不对 SomeClass 进行静态引用。这就是 class 未加载的原因。
因此,按照您的示例,在 class
中添加一个静态字段public class SomeClass {
static {
System.out.println("static block");
}
static String abc = "abc";
}
SomeClass 被加载到:
SomeClass foo = new SomeClass();
或
System.out.println(SomeClass.abc);
Isn't the class loaded as soon as I define a variable of that type?.
是的,它被加载1,但是它不会因为声明一个变量而被初始化。但是,当您创建该类型的实例或访问该类型的静态字段时,这足以触发初始化,包括静态块的执行。
查看此相关问答 - When does static class initialization happen? - 其中列出了可以触发初始化的所有内容。
How can i know if a class has already been loaded by the class loader and what are the different possibilities to have the class loaded (I know of 2: initializing the variable & using a static field/method)
我能想到的找出 class 何时加载(与初始化不同)的唯一方法是:
打开 JVM 的 class 加载程序消息(使用
-verbose:class
),或使用客户 classloader 注意到,并在看到加载 class.
的请求时做一些适当的事情
一个class实际上要被加载:
当使用
Class.forName
或类似方式显式加载时,或直接调用 classloader,为了link另一个class或
需要加载它时
在 JVM 启动时,如果 class 被命名为入口点 class。
加载/linking/初始化步骤在Chapter 12 of the JLS中指定。
1 - 事实上,SomeClass
需要在包含 main
方法的 class 是 [ 的同时加载=74=]ed;即在调用包含该局部声明的方法之前。