【问题标题】:What happens if import statements can not be resolved?如果导入语句无法解析会怎样?
【发布时间】:2012-09-26 07:19:08
【问题描述】:

我不清楚以下几点:
JVM 在需要时加载一个类,比如延迟初始化,对吧?
现在,如果类 A 执行 importB 哪个类 B 实际上不在文件系统中(例如 B.class 被删除或未交付或任何原因)
那么类A 是否被加载并运行if 没有调用类B 的方法?
或者A 根本无法运行由于无法解析导入?
A已加载并运行到某个点?

【问题讨论】:

    标签: java class jvm classloader


    【解决方案1】:

    import 语句只对编译器重要。在字节码中,所有对其他类的引用都是完全限定的。这就是为什么多余的导入在运行时并不重要。

    在您的情况下,JVM 将尝试加载所有需要加载和验证 A 的类,因此它将尝试立即加载 B,但依赖类仅在以下情况下才会延迟加载他们是需要的。查看以下示例:

    public class A {
    
        public static void bar() {
            new B().foo();
        }
    
        public static void main(String[] args) {
            //bar();
        }
    
    }
    

    编译A.java并删除B.class。如果不调用 bar() 方法,您的程序将运行得很好。但是一旦你取消注释一段实际使用B 类的代码,你会变得讨厌:

    Exception in thread "main" java.lang.NoClassDefFoundError: B
        at A.bar(A.java:4)
        at A.main(A.java:8)
    Caused by: java.lang.ClassNotFoundException: B
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
        ... 2 more
    

    如果B 不可用,您将获得NoClassDefFound 或类似名称。

    【讨论】:

    • 所以这会在尝试解析imports?Right 时发生。正在构造类A
    • @Jim:不,JVM解析任何导入,导入在编译期间被读取和丢弃。它们不存在于字节码中。在.class 文件中,所有类都是完全限定的。
    • +1 我很喜欢它详细说明为什么“问题 X”永远不会成为问题并且他们回来了;所以这是一个真正的问题。哈哈。
    • @TomaszNurkiewicz:在您的代码中,我假设您忘记了importB
    • @Jim:我在同一个包中测试这个,所以不需要导入。随意使用相同的测试代码,但在不同的包中。但我保证结果是一样的。
    【解决方案2】:

    如果 A.class 需要缺少 B.class。 A.class 无法加载。

    加载类是recursion operation

    当 A.class 需要 B.class 时,JVM 在 PermGen 中搜索 B.class。如果 B.class 被加载并存储在 PermGen 中,JVM 将 not reload B.class 但直接从 PermGen 获取它,否则 JVM 将递归加载 B.class。

    当JVM找不到B.class时,抛出NoClassDefFoundError

    See more about NoClassDefFoundError in [Java Specification] :page 319.

    【讨论】:

    • 可以。但问题是究竟是什么时候抛出这个异常
    猜你喜欢
    • 2016-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-11
    • 2017-03-05
    • 1970-01-01
    相关资源
    最近更新 更多