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

时间:2014-09-27 11:12:03

标签: java templates generics inheritance static

为了解释我将使用一个例子

//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将超类的初始值超过子类,为什么将子类静态初始化的所有信息在被模板化时被隐藏?

1 个答案:

答案 0 :(得分:1)

Subclass ins永远不会初始化,因此静态块永远不会运行。

根据JLS 12.4.1. "When Initialization Occurs ",只在以下情况下初始化一个类:

  • 创建了一个类的实例
  • 调用类中声明的静态方法
  • 访问类中声明的静态非常量字段
  • 该类是顶级类,并且在类中嵌套嵌套在语句中的断言语句

如果通过声明它的类的子类访问字段,则它具有与使用声明它的类调用它相同的效果。

使用反射也可能导致初始化。

Subclass没有满足这些条件,因此永远不会执行静态块。


如果Subclass已初始化,则会获得预期结果,例如如果你使用这个主要方法:

public static void main(String[] args) {
    new Subclass();
    System.out.print(GetTypeInfo(Subclass.class));
}