什么是Java中的即时加载?

什么是Java中的即时加载?,java,Java,我在Java中遇到过两个类SpringNestedRuntimeException和AbstractApplicationContext,这两种情况都使用静态代码块解决了相同的类装入器问题,但它们的使用方式令人困惑 混淆之处在于在静态代码块中调用ClassName.class.getName(),这如何解决类装入器问题 static { // Eagerly load the ContextClosedEvent class to avoid weird classloader

我在Java中遇到过两个类Spring
NestedRuntimeException
AbstractApplicationContext
,这两种情况都使用静态代码块解决了相同的类装入器问题,但它们的使用方式令人困惑

混淆之处在于在静态代码块中调用
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());

任何专家建议将不胜感激


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

classyourclass{
静止的{
//急切地加载ContextClosedEvent类以避免奇怪的类加载器问题
//WebLogic 8.1中的应用程序关闭。(Dustin Woods报告)
ContextClosedEvent.class.getName();
}
}
第二种情况下,
ContextClosedEvent
将在代码运行时被加载,
loadClass
方法将被调用2次。第一次是用于
ContextClosedEvent.class
reference(由JVM调用),第二次是手动调用

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

主类{
公共静态void main(字符串[]args)引发ClassNotFoundException{
Thread.currentThread()
.getContextClassLoader().loadClass(ContextClosedEvent.class.getName());
}
}
要查看静态块的工作方式,请运行此示例

主类{
公共静态void main(字符串[]args){
System.out.println(“调用的主方法”);
}
静止的{
System.out.println(“调用的静态块”);
}
}

“渴望”只是意味着他们在真正需要类之前加载它(通常JVM会在第一次使用时加载它)。他们在这里通过使用
静态
初始值设定项来实现,该初始值设定项通过对类执行一些(无用的)操作来强制加载该类。它可能修复了类加载器的问题,因为线程类加载器在第一次使用时延迟完成时可能会有所不同。但我同意你的说法,这是一种黑客行为。我认为这个链接可以帮助你,为了获得一些知识和信息,在你的调用中,你将尝试加载同一个类两次。@这样,对方法的调用将加载该类,使用thread的类加载程序将抛出选中的异常,他们可能希望避免使用静态代码块。正如您提到的
findLoadedClass
在这里很重要,它不仅仅是通过调用线程的类加载器(第二个代码段)来加载类,我使用VM args
-XX:+TraceClassLoading