接口只是编译时间依赖吗?

时间:2016-04-22 16:09:53

标签: java compile-time

我们说我有一个如下界面;

public interface aitf{
     public void method1();
}

和实现类;

public class a implements aitf{
 public void method1(){
  System.out.println("method 1");
 }
 public static void main(String... args){
  new a().method1();
 }
}

然后按预期运行并打印在下面。

method 1

然后如果我改变并添加一个方法并重新编译接口;

public interface aitf{
 public void method1();
 public void method2();
}

具体课程(a)仍然有效。实际上这种行为是有道理的,因为否则所有api更改都会导致问题。但是如何解释这种行为,接口只是编译时依赖性?

2 个答案:

答案 0 :(得分:1)

让我们回到 Interfaces 的根源,也就是 polymorphism

  • polymorphism 之前:

    • 控制流由系统行为决定,源代码依赖性由控制流决定。
  • polymorphism 生效后:

    • 我们通过使用 Dependency inversion 来应用 Interfaces,这使我们实现了独立的可部署性,当任何组件中的源代码发生变化时,所有这些都发生在 compile time 中。
<块引用>

编译时错误一般指的是语法或semantics对应的错误。另一方面,运行时错误是指在运行时执行代码期间遇到的错误。编译器在代码开发时检测到编译时错误

Interfaces 不存在于 Runtime,但它只存在于 compile time,因为它是在 Dependency inversion 中应用 OOP 的直接结果

在您的情况下发生的情况是,您的 classold compilationinterface 紧密相连,因此当您重新编译 new interface 时,它不会反映class 直到类也再次被 recompiled 保持 contractinterface 中的变化。

引自Docs

<块引用>

Method and Constructor Overloading: 添加重载现有方法或构造函数的新方法或构造函数不会破坏与预先存在的二进制文件的兼容性。用于每个调用的签名是在编译这些现有二进制文件时确定的;因此不会使用新添加的方法或构造函数,即使它们的签名既适用又比最初选择的签名更具体。 虽然添加新的重载方法或构造函数可能会在下次编译类或接口时导致编译时错误,因为没有最具体的方法或构造函数(第 15.12.2.5 节),但当程序执行,因为在执行时没有进行重载解析。

答案 1 :(得分:0)

Java在运行它们之前将.java文件编译成字节码.class文件,因此在重新编译之前更改接口不会影响class a。但是,如果您尝试调用a().method2(),则会因运行时错误而失败。 Java是一种编译语言而不是解释型语言,因此对.java文件的更改不会影响正在运行的代码。运行时类型系统用于类型,而不是接口或类。