如何初始化静态块?

How to initialize static blocks?

我必须处理一堆包含 static 块的静态遗留 classes。 classes 本身只是 helper classes,只有静态方法。

示例:

public abstract class Legacy {
    protected static final String[] ARRAY;

    static {
        //init that ARRAY
    }

    public static String convert(String value) {
        //makes use of the ARRAY variable
    }
}

重要提示:我无法控制源代码,因此无法修改代码。我知道这是 class 构建方式的严重设计缺陷。

问题:同时访问 class 时,如果 class 尚未初始化,我会从遗留 classes 中得到异常。所以我必须确保在应用程序启动时每个静态 class 之前都已正确初始化。

但是我怎么能这样做呢?

我试过如下:

Legacy.class.newInstance();

但这会导致以下错误:

java.lang.InstantiationException
    at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at java.lang.Class.newInstance(Class.java:374)

所以我可能做错了?

如果您只调用旧版 类 的静态方法,则无需创建实例。静态块将只执行一次(JVM 会处理它)。

看这个小例子。

class Legacy {
    static {
        System.out.println("static initializer of Legacy");
    }

    public static void doSomething() {
        System.out.println("Legacy.doSomething()");
    }
}

class LegacyDemo {
    public static void main(String[] args) {
        Legacy.doSomething();
    }
}

如果你 运行 LegacyDemo 它将打印

static initializer of Legacy
Legacy.doSomething()

静态初始化程序是线程安全的,因为它们只会 运行,并且由单个线程执行。

如果 class 由多个 classloader 加载,它们可能 运行 多次,但在这种情况下,它们实际上是在初始化另一个 class。

因此,您看到的问题不太可能是由于初始化不完整造成的。

您的 convert 方法似乎更有可能在做一些非线程安全的事情,例如修改数组。