-6

java.lang.String在java中创建了具有限定名称的类。

package java.lang;

public class String {
    public int getValue() {
        return 42;
   }
}

在主类中,我添加了以下代码。

public class Main {

    public static void main(String[] args) {
        String s = new String();
        System.out.println(s.getValue());
    }
}

代码编译得很好。当我运行代码时,它失败并出现以下错误。

 Exception in thread "main" java.lang.NoSuchMethodError:    java.lang.String.getValue()I
at com.Main.main(Main.java:12)

我必须了解它java.lang.String是由引导类加载器在运行时从 rt.jar 文件加载的。

所以,我认为类加载的顺序在编译时和运行时应该是不同的。您能否在编译时和运行时给出类加载的顺序。

4

1 回答 1

2

首先,此测试不适用于 Java 9 或更高版本。尝试编译String该类将给出此错误:

java/lang/String.java:1: error: package exists in another module: java.base
package java.lang;
^

在 Java 8 上,我得到了你看到的行为。假设调整后的String类在同一个源代码树中,Main该类会编译,但当您尝试运行它时会出现异常。

这似乎已报告为错误 4929425。解决方案是这是一个文档错误,他们澄清了javac命令的文档......虽然可能还不够。

总之,是有区别的,而且是微妙的区别。

java命令只是按以下顺序搜索:

  • 引导类路径
  • 扩展目录
  • 类路径

javac命令首先搜索源目录。如果它在那里找到源文件,它会在同一位置查找相应的类文件,并(如有必要)编译或重新编译它。如果没有找到源文件,那么它会在类路径中搜索如上所述的类文件以查找java.

请注意,需要非常仔细地阅读javac手册条目才能弄清楚这一点。很容易错过。(https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html#searching

(IMO,他们可以使手册页更清晰。但是,如果您尝试覆盖引导类路径或扩展目录中的某个类,这种不一致只会产生影响。而且您以错误的方式进行操作。基本上,这是一个边缘案例。清楚地记录晦涩的边缘案例的问题在于,您最终可能会使文档对正常情况更加混乱。)

于 2018-06-30T05:24:46.487 回答