我对Java编译器有一些疑问

Aki*_*chi 6 java compilation

我对Java Compiler有一些疑问.

我当前的目录是这样的.

??? Hoge.java
??? Sample.class
??? Sample.java
??? pattern01
?   ??? com
?       ??? cat
?           ??? Hoge.class
??? pattern02
    ??? com
        ??? cat
            ??? Hoge.class
Run Code Online (Sandbox Code Playgroud)

----- Sample.java -----

import com.cat.Hoge;

public class Sample {

    public static void main(String[] args) {
        System.out.println("hello!");
        Hoge h = new Hoge();
        h.call();
    }
}
Run Code Online (Sandbox Code Playgroud)

----- pattern01 -----

package com.cat;

public class Hoge {

    public void call() {
        System.out.println("com.cat");
        System.out.println("pattern01");
    }
}
Run Code Online (Sandbox Code Playgroud)

----- pattern02 -----

package com.cat;

public class Hoge {

    public void call() {
        System.out.println("com.cat");
        System.out.println("pattern02");
    }
}
Run Code Online (Sandbox Code Playgroud)

我像这样编译了Sample.java.

$ javac -cp pattern01 Sample.java 
Run Code Online (Sandbox Code Playgroud)

我这样执行它.

$ java -cp .:pattern01 Sample
hello!
com.cat
pattern01

$ java -cp .:pattern02 Sample
hello!
com.cat
pattern02
Run Code Online (Sandbox Code Playgroud)

pattern01和pattern02都正常结束.

但我用pattern01编译.为什么程序通常以pattern02结束?

编译器检查什么?编译器只检查类名吗?

JB *_*zet 8

类在运行时解析.您在类路径中使用Hoge类的版本编译了客户端类(Sample),并使用该类的另一个版本运行它.由于该类仍然兼容(相同的包,相同的名称,相同的方法签名),一切顺利.

这就是允许使用给定版本的库(或JDK)编译类,但仍然使用同一库(或JDK)的另一个版本运行它.如果这是不可能的,那么构建可重用库将是一场噩梦,因为每个库都必须针对每个版本的JDK和每个依赖库的每个版本进行编译.