为了解释,我将使用一个示例
//Superclass.java
public class Superclass
{
static String TypeInfo = "Superclass";
}
//Subclass.java
public class Subclass extends Superclass
{
static {
TypeInfo = "Subclass";
}
}
//Main.java
public class Main {
public static void main(String[] args)
{
System.out.print(GetTypeInfo(Subclass.class));
}
public static <T extends Superclass> String GetTypeInfo(Class<T> c)
{
return T.TypeInfo;
}
}
当类被模板化时,来自类加载器的所有信息似乎都丢失了,或者jvm将超类的初始值置于子类之上,为什么子类静态初始化的所有信息在模板化时都会被隐藏?
Subclass
从未初始化,因此静态块从未运行。
根据JLS 12.4.1。"初始化发生时"类仅在以下情况下初始化:
- 将创建该类的实例
- 调用类中声明的静态方法
- 访问类中声明的静态非常量字段
- 该类是顶级类,执行嵌套在该类中的断言语句
如果一个字段是通过声明它的类的子类访问的,那么它的效果与使用声明它的类别调用它的效果相同。
使用反射也可能导致初始化。
对于Subclass
,这些条件都不满足,因此从不执行静态块。
如果Subclass
被初始化,你会得到预期的结果,例如,如果你使用这个主要方法:
public static void main(String[] args) {
new Subclass();
System.out.print(GetTypeInfo(Subclass.class));
}