我对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结束?
编译器检查什么?编译器只检查类名吗?
类在运行时解析.您在类路径中使用Hoge类的版本编译了客户端类(Sample),并使用该类的另一个版本运行它.由于该类仍然兼容(相同的包,相同的名称,相同的方法签名),一切顺利.
这就是允许使用给定版本的库(或JDK)编译类,但仍然使用同一库(或JDK)的另一个版本运行它.如果这是不可能的,那么构建可重用库将是一场噩梦,因为每个库都必须针对每个版本的JDK和每个依赖库的每个版本进行编译.