使用超类类型过滤模板可以删除对超类中静态变量的修改



为了解释,我将使用一个示例

//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));
}

最新更新