java - 我可以保证静态初始化程序在 Java 中的运行顺序吗?

标签 java inheritance static initialization static-initializer

我有一个 Set 类(这是 J2ME,所以我对标准 API 的访问权限有限;只是为了解释我明显的轮子改造)。我正在使用我的集合类在类和子类中创建常量集合。它看起来像这样......

class ParentClass
{
    protected final static Set THE_SET = new Set() {{
        add("one");
        add("two");
        add("three");
    }};
}


class SubClass extends ParentClass
{
    protected final static Set THE_SET = new Set() {{
        add("four");
        add("five");
        add("six");
        union(ParentClass.THE_SET); /* [1] */
    }};
}

一切看起来都很好,除了 [1] 处的行导致空指针异常。据推测,这意味着子类中的静态初始化程序在父类的静态初始化程序之前运行。这让我感到惊讶,因为我原以为它会先在任何新导入中运行静态 block ,然后再在实例化的子类中运行任何静态 block 。

我的假设是否正确?有什么方法可以控制或解决此行为?

更新:

事情甚至更奇怪。我改为尝试这样做(注意“new ParentClass()”行):

class ParentClass
{
    public ParentClass()
    {
        System.out.println(THE_SET);
    }

    protected final static Set THE_SET = new Set() {{
        add("one");
        add("two");
        add("three");
    }};
}


class SubClass extends ParentClass
{
    protected final static Set THE_SET = new Set() {{
        System.out.println("a");
        new ParentClass();
        System.out.println("b");
        add("four");
        System.out.println("c");
        add("five");
        System.out.println("d");
        add("six");
        System.out.println("e");
        union(ParentClass.THE_SET); /* [1] */
        System.out.println("f");
    }};
}

输出很奇怪:

a
["one", "two", "three"]
b
c
d
e
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException

因此 ParentClass 已初始化,但子类无法在其静态初始化程序中访问它。

最佳答案

这是您要实现的目标吗?或者您是否需要 Set 接口(interface)的本地实现?

class ParentClass
{
    protected final static Set THE_SET;

    static {
        THE_SET = new HashSet();
        THE_SET.add("one");
        THE_SET.add("two");
        THE_SET.add("three");
    }
}


class SubClass extends ParentClass
{
    protected final static Set THE_SECOND_SET;

    static {
        THE_SECOND_SET = new HashSet();
        THE_SECOND_SET.add("four");
        THE_SECOND_SET.add("five");
        THE_SECOND_SET.add("six");
        union(ParentClass.THE_SET); /* [1] */
    }
}

关于java - 我可以保证静态初始化程序在 Java 中的运行顺序吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/793422/

相关文章:

java - Room Persistence 库 - 带有 List<Video> 的嵌套对象,@Embedded 不起作用。

c# - 如何在某些情况下使用不同的基类构造函数?

c# - 在派生类中强制声明属性

php - Inherited() 标志 : propertyName vs. storageName

c++ - C++ 中的局部/静态变量作用域

methods - 从特征实现静态方法时名称解析错误

C 函数输入的静态变量

java - 什么是 Struts .struts.mex 文件

java - 遍历 Java 中的 HashMap

java - 如何使我的字符串生成器标签 ID、名称、地址加粗