gpt4 book ai didi

java - 什么时候加载 Java 类?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:43:10 25 4
gpt4 key购买 nike

我在互联网上搜索了几个多小时,没有得出任何结论。

最近我决定将 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 会在执行类中的第一行代码之前加载类的深度。是这样吗?

最佳答案

这个问题没有简单的答案。该规范为不同的实现策略留出了空间,即使在一个实现中,它也将取决于如何使用该类。此外,您的问题更多是关于“它什么时候会失败”,这取决于它可能失败的原因,例如一个类可能会在某个时间点被加载以验证它的存在,但初始化会在它真正第一次被使用的时候被初始化。在这两个时间点,操作都可能失败,导​​致 NoClassDefFoundError

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

  • 必须在链接时解析的类(例如父类(super class))
  • 必须在验证时加载的类
  • 加载可以推迟到第一次实际使用的类

在您的情况下,BouncyCaSTLeProvider 必须在验证时间 加载,而不是在第一次实际使用时加载,因为您传递的是 new BouncyCaSTLeProvider() 的结果 作为方法 Security.insertProviderAt(…) 的参数, validator 必须检查该类是否实际扩展了该方法的形式参数要求的 Provider 类型。

何时进行验证,也是特定于实现的,因为至少允许以下可能性:

  • 热切地遍历所有引用的类
  • 关于包含类的加载或其首次使用
  • 关于包含方法的第一次使用
  • 就在执行违规指令之前

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

但是为了与其他 JVM 兼容,将它移到另一个类中更安全,但是为了符合所有可能的 JVM,您甚至需要通过反射加载其他类以避免直接引用可以通过急切的实现来遍历(或者首先通过 Class.forName("… .BouncyCaSTLeProvider").newInstance() 反射性地实例化 BouncyCaSTLeProvider)。

关于java - 什么时候加载 Java 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34259275/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com