棘手的编译器行为

时间:2010-03-23 09:19:59

标签: java javac

简单的java代码段。它有三个类。编译代码后,请删除A.class然后执行代码。代码仍然运行,为什么它不检查A的字节代码是否存在?

class A {
    static {
        System.out.println("In the class A");
    }

    public A() {
    }
}

class B {
    private A a = null;

    static {
        System.out.println("In the class B");
    }

    public B() {
        a = new A();
    }
}

public class ExampleLinkage {
    static {
        System.out.println("In the class A");
    }

    public ExampleLinkage(String str) {
    }

    public static void main(String args[]) {
        try {
            System.out.println("In the main method of ExampleLinkage");
            Class.forName("com.bt.rtti.B");
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

4 个答案:

答案 0 :(得分:5)

我猜想,即使在B中有一个实例,也不需要加载类A,因为你永远不会实例化B的实例。

JVM在加载类时非常懒惰。当你实例化那个类的对象时(第一次),当你用Class.forName()显式加载一个类,或者你以一种需要信息的方式引用它时,它会加载它们(尝试访问一个来自B的静态初始化程序的A的静态成员,并看到A将被加载。

答案 1 :(得分:1)

由于您没有重新编译它,只需运行该类。

答案 2 :(得分:0)

代码中没有使用A类(即在主方法中)。

在运行时,类在使用时加载。那时,你会得到一个ClassNotFoundError。但是如果你没有使用这门课程,那就不需要它了。

尝试创建B的实例(需要A的实例),然后就会出错。

答案 3 :(得分:0)

除了Gordon的答案之外,你只是在运行这个类,并且不需要A类,如果你在A中调用了A的构造函数或引用了静态字段或方法,那么你会得到你期望的ClassNotFoundException