JVM尝试加载未调用的类

时间:2014-07-15 19:44:14

标签: java

我正在编写代码,将功能添加到' mod'如果它存在于类路径中(由pixelmonPresent引用)

PixelHammerTool extends ItemHammer

ItemHammer仅在pixelmon存在时才存在

我有的问题是,如果我在课堂上这样做(同一个包)

if(Basemod.pixelmonPresent) {
rubyHammer = new PixelHammerTool(Basemod.RUBY, "pixelutilitys:RubyHammer", "rubyHammer");
}

这将导致PixelHammerTool上找不到的课程, 如果if语句为false,我该怎么做呢?

2 个答案:

答案 0 :(得分:2)

为什么简单明了:因为当一个类被加载时,它所引用的所有类也被加载。 (实际上它们首先加载。)

避免它也不复杂,虽然代码看起来不太好:你需要使用Class.forName()加载带有反射的类,从返回的数组中找到你想要的构造函数按Class.getConstructors(),然后使用Constructor.newInstance()创建实例。

请注意,虽然如果它只在代码中发生几次,这个解决方案很好,如果你发现自己做了很多,那么你应该寻找一个依赖注入框架,它将为你做繁重的工作。 / p>

答案 1 :(得分:2)

在规范的Linking部分下,我们看到了这一点:

  

例如,Java虚拟机实现可以选择在使用时单独解析类或接口中的每个符号引用(" lazy"或" late" resolution),或者在课程被验证时立即解决所有问题("渴望"或"静态"解决方案)。这意味着在一些实现中,在初始化类或接口之后,解析过程可以继续。无论采用哪种策略,在解析期间检测到的任何错误都必须抛出到程序中(直接或间接)使用对类或接口的符号引用的位置。

因此,必须定义常量是依赖于实现的,基于类加载器。您所看到的行为与“渴望”的行为一致。提到的解决方案:当您在代码中引用PixelHammerTool时,即使它对于永远不会被命中的运行时路径,类加载器也会尝试在其定义中进行链接,不存在。

此策略使JVM启动较慢但在运行时执行得更快,这通常是我熟悉的所有实现中采用的策略。实际上,默认类加载器的名称为" bootstrap类加载器"因为它有这种行为 - 在JVM引导时加载类。

你可以通过反射来实例化类,就像biziclop建议的那样(更简单的路径),它强制在运行时链接,或者找到或创建一个懒惰地实例化类的类加载器。