javajava-6java-5

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


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

Solution

  • 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.