Let's say I'm using Java 11 javac, but I'm using the --source and --target options set to 1.8 so that my source code will be considered Java 8 and the output .class files will be compatible with Java 8. My goal is to produce .class files that can run on a Java 8 JVM.
And let's say I have the following Java 8 code I'm compiling:
import java.nio.ByteBuffer;
…
ByteBuffer byteBuffer = …; //init somehow
byteBuffer.flip(); //what ends up in the `.class` file?
The question is: what should Java 11 javac put in the .class file to link the byteBuffer.flip() method call? Before you answer, consider this:
- Neither Java 8
ByteBuffernor Java 11ByteBufferdeclare theflip()method at theByteBufferlevel. ByteBufferis a direct subclass ofBuffer. There is both a Java 8Buffer.flip()and a Java 11Buffer.flip()declared in theBufferAPI for both versions.- In the Java 8 source code, there is no
ByteBuffer.flip()method. - But in the Java 11 source code,
ByteBufferoverrides theBuffer.flip()method like the following. The purpose apparently was to use covariance so that in Java 11ByteBuffer.flip()would conveniently return aByteBufferinstead of aBuffer.@Override public ByteBuffer flip() { super.flip(); return this; }
So to restate the question: Should Java 11 javac, with the --source and --target options set to 1.8, generate a .class file that links to Buffer.flip() or to ByteBuffer.flip()? If it is the former, then how does it know not to include ByteBuffer.flip() instead, as the (Java 8) code clearly references ByteBuffer.flip() and the (Java 11) compiler sees that there is a ByteBuffer.flip() method in the runtime? But if it is the latter, then how can I ever know that my 100% correct Java 8 compatible source code, when compiled using Java 11, will run on a Java 8 JRE even if I use the --source and --target options to indicate Java 8? (Note that OpenJDK 11.0.5 seems to choose the latter option. But which is correct?)
(Note that I'm using the word "link" loosely; I'm not currently well-versed in what bytecode is generated. All I know is that the class file has come reference somehow to Buffer.flip() or ByteBuffer.flip(); and if this method can't be found at runtime, the JVM will throw an exception such as: java.lang.NoSuchMethodError: java.nio.ByteBuffer.flip()Ljava/nio/ByteBuffer;.)
As a bonus question, I wonder whether using the --release option set for Java 8 would change the answer. But note that I can't use the --release option (equivalent to the Maven <release> compiler plugin option) because I want my Maven project to be buildable with both Java 8 and Java 11.