棘手的编译器行为

Nee*_*raj 1 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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Omr*_*dan 5

我猜想在任何时候都不需要加载类A,即使它在B中有一个实例,因为你永远不会实例化B的实例.

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