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

huangapple go评论77阅读模式
英文:

Why is javac -source 1.5 allowing @Override on interface methods?

问题

以下是您要翻译的内容:

这里有一些在1.5版本下是非法的示例Java代码,如果我理解正确的话
(因为直到Java 1.6版本之前@Override不能用于覆盖接口方法):

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

我想在我的源代码中找到所有这种在1.5版本下不兼容的问题,
因此我在我的Ubuntu Linux机器上安装了一个支持Java 1.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应该做什么?

值得注意的是,-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
英文:

Here is some sample java code that is illegal under 1.5, if I understand correctly
(since @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() {}
  }
} 

I want to find all such 1.5-incompatibilities in my source code,
so I installed a java1.5-capable compiler on my ubuntu linux machine:

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

and compiled the above java source code:

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

I expected the above java code to be rejected. But it
apparently compiled successfully, in spite of the illegality under 1.5.

What's going on? Am I misunderstanding the 1.5 rules about @Override?
Or am I misunderstanding what -source 1.5 is supposed to do?

FWIW, I notice that -source 1.4 does give the expected error:

${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

答案1

得分: 5

查看Oracle关于javac的Java SE8文档,它说:

> ...
>
> -source release
>
> 指定接受的源代码版本。允许使用以下release的值:
>
> ...
>
> - 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,我们会得到一个编译错误,因为注解是在Java 1.5中引入的,因此包括保留在运行时的注解可能会更改程序的行为,编译器不能忽略它们。


如果我们想要查找与Java SE 5不兼容的所有情况,我建议从Oracle存档中下载Java SE 5 JDK,并尝试使用该JDK编译项目。

英文:

Looking at Oracle's documentation of javac for Java SE8 it says:

> ...
>
> -source release
>
> Specifies the version of source code accepted. The following values for release are allowed:
>
> ...
>
> - 1.5
>
> The compiler accepts code containing generics and other language features introduced in Java SE 5.
>
> - 5
>
> Synonym for 1.5.
>
> - 1.6
>
> No language changes were introduced in Java SE 6. However, encoding errors in source files are now reported as errors instead of warnings as in earlier releases of Java Platform, Standard Edition.
>
> ...

Notice that the site says that "no language changes were introduced in Java SE 6". Thus, the fact that @Override could be used to assert that interface-methods were overridden seems to be not regarded as a language change; rather, the fact that it wasn't previously allowed may be regarded as simply a bug in some Java 5 SDKs compilers.

This behaviour is rectified since @Override can be omitted after compilation and the JDK 8 compiler understands (and validates) the annotation. Thus, the annotation has no effect whatsoever on the created bytecode.

With -source 1.4, we get a compilation error since Annotations were introduced with Java 1.5, thus including annotations that are retained at runtime could change the behaviour of the program and the compiler must not ignore them.


If we want to find all incompatibilites with Java SE 5, I recommend downloading Java SE5 JDK from the Oracle Archive and trying to compile the project with this JDK.

huangapple
  • 本文由 发表于 2020年8月23日 07:06:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/63541942.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定