java - 使用父类(super class)类型过滤模板可以删除对父类(super class)中静态变量的修改

标签 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采用父类(super class)而不是子类的初始值,为什么子类静态初始化的所有信息在模板化时都会被隐藏?

最佳答案

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

根据JLS 12.4.1. "When Initialization Occurs "类仅在以下情况下初始化:

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

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

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

Subclass 都不满足这些条件,因此静态 block 永远不会执行。

<小时/>

如果 Subclass 已初始化,您将得到预期的结果,例如如果你使用这个主要方法:

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

关于java - 使用父类(super class)类型过滤模板可以删除对父类(super class)中静态变量的修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26074023/

相关文章:

java - 如何在 spring 中禁用调试日志

java - Facebook 集成应用程序可以在模拟器中完美运行,但不能在 Android 设备上运行

java - 什么时候在一行上有多个 java 语句是合适的?

python - 如何使用 Jinja2 模板引擎生成 json

c++ - 如何根据 operator() 参数泛化一个类?

带有序号指示符的月中日期的java日历显示名称样式

java - 使用泛型的泛型/系统架构的问题

delphi - 关于加入 TObjectlists

java - 强制 Java 方法返回类型以适应特定的通用签名

c++: 无法实例化 std::set 模板类