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

izb*_*izb 5 java inheritance static initialization static-initializer

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

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] */
    }};
}
Run Code Online (Sandbox Code Playgroud)

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

我在这个假设中是对的吗?有没有办法控制或解决这种行为?

更新:

事情甚至更奇怪.我尝试了这个(注意'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");
    }};
}
Run Code Online (Sandbox Code Playgroud)

输出很奇怪:

a
["one", "two", "three"]
b
c
d
e
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException
Run Code Online (Sandbox Code Playgroud)

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

Eli*_*jah 7

这是你想要完成的吗?或者您是否需要Set接口的本地实现?

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] */
    }
}
Run Code Online (Sandbox Code Playgroud)