为什么javac -source 1.5在接口方法上允许@Override?

问题描述

如果我理解正确,以下是一些示例代码,这些代码在1.5以下是非法的 (自@Override could not be used for overrides of interface methods until java 1.6起):

public class A { 
  public static interface MyInterface { 
    public void myInterfaceMethod();
  }
  public static class MyClass implements MyInterface { 
    @Override public void myInterfaceMethod() {}
  }
} 

我想在我的源代码中找到所有这种1.5不兼容的地方, 所以我在ubuntu linux机器上安装了支持java1.5的编译器:

sudo apt install openjdk-8-jdk
JAVAROOT=/usr/lib/jvm/java-1.8.0-openjdk-amd64
${JAVAROOT}/bin/javac -version
# javac 1.8.0_232

并编译了上面的java源代码

${JAVAROOT}/bin/javac -source 1.5 -Xlint:all -Xlint:-options A.java

我希望上面的Java代码被拒绝。但它 尽管在1.5下是非法的,但显然编译成功。

这是怎么回事?我是否误解了@Override的1.5条规则? 还是我误解了-source 1.5应该做什么?

FWIW,我注意到-source 1.4确实给出了预期的错误

${JAVAROOT}/bin/javac -source 1.4 -Xlint:all -Xlint:-options A.java
A.java:6: error: annotations are not supported in -source 1.4
      @Override public void myInterfaceMethod() {}
       ^ 
  (use -source 5 or higher to enable annotations)
1 error

解决方法

看着Oracle's documentation of javac for Java SE8,它说:

...

-源版本

指定接受的源代码版本。允许以下释放值:

...

  • 1.5

    编译器接受包含Java SE 5中引入的泛型和其他语言功能的代码。

  • 5

    1.5的同义词。

  • 1.6

    Java SE 6中未引入语言更改。但是,现在将源文件中的编码错误报告为错误,而不是像Java Platform Standard Edition的早期版本中的警告一样。

...

通知该网站说:“ Java SE 6中未引入任何语言更改” 。因此,可以使用@Override来断言接口方法已被覆盖的事实似乎不被视为语言的改变;相反,在某些Java 5 SDK编译器中,以前不允许使用此事实可能只是一个错误。

此行为已得到纠正,因为编译后可以忽略@Override,并且JDK 8编译器可以理解(并验证)注释。因此,注释对创建的字节码没有任何影响。

使用-source 1.4以来,我们会收到Annotations were introduced with Java 1.5以来的编译错误,因此包括在运行时保留的注释可能会改变程序的行为,并且编译器不得忽略它们。


如果我们想找到与Java SE 5不兼容的所有功能,建议您下载Java SE5 JDK from the Oracle Archive(尽管您必须创建一个Oracle帐户),然后尝试使用此JDK编译项目。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...