java static initializer called twice

2019-09-13 18:49发布

问题:

static boolean isClassLoaded(String fullname) {
    try {
        Class.forName(fullname, false, Loader.instance().getModClassLoader());
        return true;
    } catch (Exception e) {
        return false;
    }
}

does this method has potential to trigger fullname's static initializer ? i have problem with static initializer called twice. when i try to check if class loaded using isClassLoaded and try to use that class, i get error because of constructor called twice. anyone know what is problem with Class.forName(fullname, false, Loader.instance().getModClassLoader()); ?

回答1:

The second parameter is a flag called "initialize".

From the docs:

The class is initialized only if the initialize parameter is true and if it has not been initialized earlier.

So, if initialize is set to false, it will not execute your static initializers.

Self-contained example

package test;

public class Main {

    public static void main(String[] args) throws Exception {
        Class.forName("test.Main$Foo", false, Main.class.getClassLoader());
        System.out.println("blah");
        Class.forName("test.Main$Foo", true, Main.class.getClassLoader());
    }

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

}

Output

blah
Foo static initializer

Note it would always print Foo static initializer only once, but here, it prints blah first, i.e. the first Class.forName invocation did not execute the static initializer.