用Java渴望加载什么?

时间:2019-06-17 11:19:59

标签: java

我在Spring NestedRuntimeExceptionAbstractApplicationContext的两个类中遇到了Java的急切加载,这两种情况都使用静态代码块解决了相同的Class loader问题,但是使用它们的方式是令人困惑。

困惑是关于在静态代码块中对ClassName.class.getName()的调用,这如何解决类加载器问题。

static {
        // Eagerly load the ContextClosedEvent class to avoid weird classloader issues
        // on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
        ContextClosedEvent.class.getName();
    }

如果我要这样做,我将获得类加载器并手动加载该类

Thread.currentThread()
.getContextClassLoader().loadClass(ContextClosedEvent.class.getName());

任何专家的建议将不胜感激。

Reference

1 个答案:

答案 0 :(得分:4)

在第一种情况下,例如下面的示例,ContextClosedEvent将在使用YourClass后立即加载。

class YourClass {
    static {
        // Eagerly load the ContextClosedEvent class to avoid weird classloader issues
        // on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
        ContextClosedEvent.class.getName();
    }
}

第二种情况,ContextClosedEvent将在您的代码运行时加载,loadClass方法将被调用2次。第一次是供ContextClosedEvent.class参考(由JVM调用),第二次是您的手动调用。

第一次ContextClosedEvent实际上是从类路径加载的。第二次,这取决于您的ContextClassLoader。默认情况下,JVM的类加载器将findLoadedClass而不是再次加载该类。
作为下面的示例,loadClass方法运行时将调用main方法两次。

class Main {
    public static void main(String[] args) throws ClassNotFoundException {
        Thread.currentThread()
            .getContextClassLoader().loadClass(ContextClosedEvent.class.getName());
    }
}

要查看静态块的工作原理,请运行以下示例

class Main {
    public static void main(String[] args) {
        System.out.println("main method invoked");
    }
    static {
        System.out.println("static block invoked");
    }
}