以下Java代码不会调用类的静态初始化程序B.为什么?
码:
class A
{
static
{
System.out.println("A static init");
}
public static void f()
{
System.out.println("f() called");
}
}
class B extends A
{
static
{
System.out.println("B static init");
}
}
public class App
{
public static void main( String[] args)
{
B.f(); //invokestatic #16 // Method com/db/test/B.f:()V
}
}
Run Code Online (Sandbox Code Playgroud)
节目输出:
A static init
f() called
Run Code Online (Sandbox Code Playgroud)
在JDK 1.8.0_25上测试过
Era*_*ran 13
没有"静态构造函数"这样的东西.它是一个静态初始化块,只在初始化类时执行.由于您正在调用类A的静态方法(即使您通过类B引用它),因此无需初始化类B.调用B.f();与调用相同A.f();.
如果创建类B的实例或访问类B的静态成员/方法,则将执行类B的静态初始化块.
以下是触发类初始化的唯一条件(JLS 12.4.1):
类或接口类型T将在第一次出现以下任何一个之前立即初始化:
Run Code Online (Sandbox Code Playgroud)T is a class and an instance of T is created. T is a class and a static method declared by T is invoked. A static field declared by T is assigned. A static field declared by T is used and the field is not a constant variable (§4.12.4). T is a top level class (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.
由于只有类A定义了方法f(,所以类B被加载但未初始化.
你可以java -verbose:class MyClassName用来检查这个.
在jdk6/jdk 8机器上,将打印.
[Loaded App from file:/C:/XXXX/]
[Loaded A from file:/C:/XXXXXX]
[Loaded B from file://C:/XXXXXXX]
A static init
f() called
Run Code Online (Sandbox Code Playgroud)
类B将被懒惰地初始化但是贪婪地加载(因为它被引用).
将您的代码更改为A.f().然后你会看到B没有加载.
[Loaded App from file:/C:/XXXX/]
[Loaded A from file:/C:/XXXXX]
A static init
f() called
Run Code Online (Sandbox Code Playgroud)
注意:类加载和初始化是两回事.检查文档以Class.forName()获取详细信息.
| 归档时间: |
|
| 查看次数: |
259 次 |
| 最近记录: |