我发现 Java 1.7_51 和 Java 1.8_20 之间有些困难。
初始情况:
一个界面:
interface InterfaceA {
public void doSomething();
}
两个类:
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: error: cannot access InterfaceA a.doSomething();
class file for InterfaceA not found 1 error
我用 java 1.7 试过同样的方法.. -> javac *.java 编译器完成后,我删除了 InterfaceA.java 和 InterfaceA.class 文件。 但是知道我没有收到错误消息..
有人能给我解释一下吗?
..抱歉我的英语不好..
最佳答案
正式规范描述了寻找调用表达式的目标方法的过程,首先搜索所有适用的方法,然后选择最具体的方法,如果没有歧义则成功。
比较 JLS 15.12.2.1. Identify Potentially Applicable Methods
The class or interface determined by compile-time step 1 (§15.12.1) is searched for all member methods that are potentially applicable to this method invocation; members inherited from superclasses and superinterfaces are included in this search.
在您的情况下,可以推断在 ClassA
中找到的方法与编译器无法在 InterfaceA
中找到更具体的方法完全匹配,然而,规范并没有强制要求编译器必须在此时停止,从而使搜索短路。这是编译器可能具有的优化,但按照正式指定的方式实现搜索,即首先搜索整个类型层次结构,然后再进行选择,是合适的。
考虑到所有新的 Java 8 功能和类型推断的过程是多么微妙和复杂,可以理解当前的实现更加保守而不是优化。
关于Java 8 接口(interface)/类加载器更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26799874/