Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ClassLoader:是否可以配置为使用惰性而非静态解析?_Java_Jvm_Classloader - Fatal编程技术网

Java ClassLoader:是否可以配置为使用惰性而非静态解析?

Java ClassLoader:是否可以配置为使用惰性而非静态解析?,java,jvm,classloader,Java,Jvm,Classloader,我读到它是关于分辨率的 解析是检查从测试到其他类和接口的符号引用的过程,方法是加载提到的其他类和接口,并检查引用是否正确 在初始链接时,解析步骤是可选的。一个实现可以解析早期链接的类或接口的符号引用,甚至可以解析进一步递归引用的类和接口的所有符号引用 相反,一个实现可以选择仅在符号引用被积极使用时解析它;对所有符号引用一致使用此策略将代表“最懒惰”的解析形式。在这种情况下,如果测试有多个对另一个类的符号引用,那么引用可能会在使用时一次解析一个,或者如果这些引用在程序执行期间从未使用过,则可能根本

我读到它是关于分辨率的

解析是检查从测试到其他类和接口的符号引用的过程,方法是加载提到的其他类和接口,并检查引用是否正确

在初始链接时,解析步骤是可选的。一个实现可以解析早期链接的类或接口的符号引用,甚至可以解析进一步递归引用的类和接口的所有符号引用

相反,一个实现可以选择仅在符号引用被积极使用时解析它;对所有符号引用一致使用此策略将代表“最懒惰”的解析形式。在这种情况下,如果测试有多个对另一个类的符号引用,那么引用可能会在使用时一次解析一个,或者如果这些引用在程序执行期间从未使用过,则可能根本不会解析

例如,实现可以选择仅在使用时单独解析类或接口中的每个符号引用(延迟解析或延迟解析),或者在验证类时一次性解析所有符号引用(静态解析)。这意味着在某些实现中,在类或接口初始化之后,解析过程可能会继续

所以我的问题是我是否可以选择/强制使用惰性初始化?也许它需要编写一个自定义类加载器?或者启动时类加载器中的ClassNotFoundException可能会被忽略


我在
main
中有一个对象的有条件创建,它实际上不应该发生,并且jar中缺少相应的类。但是,即使在
main
开始执行之前,
NoClassDefFoundError
也会被抛出。

NoClassDefFoundError错误:

如果Java虚拟机或
类加载器
实例 尝试加载类的定义(作为普通方法调用的一部分 或者作为使用
new
表达式创建新实例的一部分) 并且找不到该类的定义

该错误与实例化相关类的实例无关。因此,对于您的示例,如果“outer”类为该类型定义了一个字段,就足够了。无法加载包含main的类,因为它所依赖的类型在运行时在类路径上不可用

如果有疑问,请查看导入语句并删除要动态加载的类的导入*)。然后尝试删除错误标记,而不再次为该类添加导入


*)-我假设此动态加载的类位于不同的包中,您需要为其导入。

NoClassDefFoundError错误:

如果Java虚拟机或
类加载器
实例 尝试加载类的定义(作为普通方法调用的一部分 或者作为使用
new
表达式创建新实例的一部分) 并且找不到该类的定义

该错误与实例化相关类的实例无关。因此,对于您的示例,如果“outer”类为该类型定义了一个字段,就足够了。无法加载包含main的类,因为它所依赖的类型在运行时在类路径上不可用

如果有疑问,请查看导入语句并删除要动态加载的类的导入*)。然后尝试删除错误标记,而不再次为该类添加导入


*)-我假设这个动态加载的类位于不同的包中,您需要为其导入。

您不能使用Oracle的JVM


根据定义,类加载器不能延迟类的加载。链接的顺序和时间是特定于实现的。AFAIK大多数JVM选择尽早链接,有些甚至在编译时链接(请参阅Excelsior JET以获取此示例)。

您不能使用Oracle的JVM

根据定义,类加载器不能延迟类的加载。链接的顺序和时间是特定于实现的。AFAIK大多数JVM选择尽早链接,有些甚至在编译时链接(请参阅Excelsior JET以获取此示例)。

考虑一下这一点

class Test2 {
}

public class Test1 {
    static Test2 test2;

    public static void main(String[] args) {
        System.out.println("Test1");
        test2 = new Test2();
    }
}
我编译了它,删除了Test2.class并运行了
java-cp。Test1
输出

    Test1
    Exception in thread "main" java.lang.NoClassDefFoundError: Test2
        at Test1.main(Test1.java:9)
    Caused by: java.lang.ClassNotFoundException: Test2
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
......
在我看来,这意味着JVM依赖项解析在默认情况下是惰性的。JVM直到第一次使用Test2.class时才注意到它丢失了

class Test2 {
}

public class Test1 {
    static Test2 test2;

    public static void main(String[] args) {
        System.out.println("Test1");
        test2 = new Test2();
    }
}
我编译了它,删除了Test2.class并运行了
java-cp。Test1
输出

    Test1
    Exception in thread "main" java.lang.NoClassDefFoundError: Test2
        at Test1.main(Test1.java:9)
    Caused by: java.lang.ClassNotFoundException: Test2
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
......

在我看来,这意味着JVM依赖项解析在默认情况下是惰性的。JVM直到第一次使用Test2.class时才注意到它丢失了。

Andreas_D说的是非常正确的:你可以按照你要求的方式解决问题。Andreas_D说的是非常正确的:你可以按照你要求的方式解决问题。谢谢,我理解你在这里的意思。但是我能做什么呢?如果你不能使用运行时已知的接口,那么你必须将实例存储为
对象
类型,并反映字段和方法。谢谢,我理解你在这里的意思。但是我能做什么呢?如果你不能使用运行时已知的接口,那么你必须将实例存储为
对象
类型,并反映字段和方法。是的,你是对的。我已经对这段代码做了实验,也在不同的包中进行了分离,放入jar,并始终在异常/错误之前获取
Test1
。但在我的真实代码中,异常是先打印的,而不是
main
中的
println
。是的,您