Java 8接口/类加载器有变化吗?

我发现Java 1.7_51和Java 1.8_20之间存在一些困难。

最初的情况:

一个界面:

interface InterfaceA { public void doSomething(); } 

两个class:

 public class ClassA implements InterfaceA { public void doSomething() { System.out.println("Hello World!"); } } public class ClassB { public static void main(String[] args) { ClassA a = new ClassA(); a.doSomething(); } } 

接下来我在编译完成后用(Java 1.8) – > javac * .java编译了类,我删除了InterfaceA.java和InterfaceA.class文件。 现在我再次尝试编译只有ClassB.java并得到错误消息:

ClassB.java:4:错误:无法访问InterfaceA a.doSomething();
找不到InterfaceA的类文件1错误

我尝试使用java 1.7 .. – > javac * .java编译完成后我删除了InterfaceA.java和InterfaceA.class文件。 但知道我没有错误信息..

有人可以解释一下吗?

.. 对不起,我的英语不好 ..

forms规范描述了查找调用表达式的目标方法的过程,首先搜索所有适用的方法,然后选择最具体的方法,如果没有歧义,则成功。

比较JLS 15.12.2.1。 确定可能适用的方法

搜索由编译时步骤1(第15.12.1节)确定的类或接口,以查找可能适用于此方法调用的所有成员方法; 从超类和超接口inheritance的成员包含在此搜索中。

在您的情况下,可以推断出ClassA找到的方法是完全匹配的,编译器无法在InterfaceA找到更具体的方法,但是,规范并未要求编译器必须在此时停止,短路搜索。 这是编译器可能具有的优化,但是像正式指定的那样实现搜索,即首先搜索整个类型层次结构然后选择,这是合适的。

鉴于该过程对于所有新的Java 8特性和类型推断有多么微妙和复杂,可以理解当前的实现更加保守而非优化。

我可以想到两种可能的解释:

  1. 也许在Java 8中添加默认方法或类型注释或其他东西意味着需要更改编译器以加载间接引用接口的类文件。

  2. 也许这只是编译器的其他一些重组的无害副作用。

无论哪种方式,它都不一定会对运行时发生的事情产生任何影响。 编译时的“修复”是不删除那样的接口类文件。