当前位置:  开发笔记 > 编程语言 > 正文

什么时候加载Java类?

如何解决《什么时候加载Java类?》经验,为你挑选了1个好方法。

我搜索了互联网超过几个小时,无法得出任何结论.

最近我决定使用BouncyCastle进行SSL,但我希望它默认关闭,这样BouncyCastle jar可能不在类路径中.

private void enableBouncyCastleForSSL() {
   if (config.isBouncyCastleEnabled()) {
        Security.insertProviderAt(new BouncyCastleProvider(), 1);
    }
} 

即使配置被禁用,它也在寻找BouncyCastle并且它因类加载器错误而失败.java.lang.NoClassDefFoundError:org/bouncycastle/jce/provider/BouncyCastleProvider

我试着只移动Security.insertProviderAt(new BouncyCastleProvider(),1); 对于一种新的方法,它表现出同样的问题.

但是当我引入一个类并在其中移动BouncyCastle时,当配置被禁用时,类加载器问题不会出现

private void setupSSLProvider() {
    if (voldemortConfig.isBouncyCastleEnabled()) {
        SetupSSLProvider.useBouncyCastle();
    }
}
public class SetupSSLProvider {
  public static void useBouncyCastle() {
    Security.insertProviderAt(new BouncyCastleProvider(), 1);
  }
}

有些文章声称Class仅在首次使用时加载.http://www.programcreek.com/2013/01/when-and-how-a-java-class-is-loaded-and-initialized/

显然,就我而言,Java8加载了类中引用的类.

所以我的理解是Java会在类中执行第一行代码之前将类加载一级.是对的吗 ?



1> Holger..:

这个问题没有简单的答案.该规范余地不同的实现策略,甚至在一个实现,这将取决于如何在类中使用.此外,您的问题更多地是关于"何时可以失败",这取决于它可能失败的原因,例如,可以在一个时间点加载类以验证其存在,但在稍后实际首次使用时初始化.在这两个时间点,操作可能会失败导致a NoClassDefFoundError.

我们可以将引用的类分为三组:

必须在链接时解析的类(例如超类)

必须在验证时加载的类

这些类的加载可以推迟到它的第一次实际使用

在您的情况下,BouncyCastleProvider必须在验证时加载,而不是第一次实际使用,因为您将new BouncyCastleProvider()as作为参数的结果传递给方法Security.insertProviderAt(…),并且验证者必须检查该类是否实际扩展了Provider该方法的形式参数所强制的类型.

验证将发生时,也是特定的实现,因为至少允许以下可能性:

热切地遍历所有引用的类

关于加载包含类或其首次使用

在包含方法的第一次使用

在执行违规指令之前

Oracle的JVM更喜欢方法的第一次使用,读取:在方法入口处验证它,因此,将调用移动到另一个不会被执行的方法,无论是否在另一个类中,在您的情况下就足够了.

但是为了与其他JVM兼容,将其移动到另一个类更安全,但为了遵守所有可能的JVM,您甚至需要通过Reflection加载这个其他类,以避免可以通过急切实现(或实例化)遍历的直接引用BouncyCastleProvider反思地通过Class.forName("… .BouncyCastleProvider").newInstance()首先).

推荐阅读
刘美娥94662
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有