Jin Kwon Jin Kwon - 1 month ago 17
Java Question

JDK8 with -source 1.7 [Default Methods]

I have the following class.

public class ZonedDateTimeToInstant {

public static void main(final String[] args)
throws NoSuchMethodException {

assert ChronoZonedDateTime.class.isAssignableFrom(ZonedDateTime.class);
final Method toInstant
= ChronoZonedDateTime.class.getMethod("toInstant");

final ZonedDateTime now = ZonedDateTime.now();
final Instant instant = now.toInstant();

System.out.println(instant);
}
}


It just compiles fine.

& javac ZonedDateTimeToInstant.java


And it fails with
-source 1.7
.

& javac -source 1.7 ZonedDateTimeToInstant.java
ZonedDateTimeToInstant.java:10: error: cannot find symbol
final Instant instant = now.toInstant();
^
symbol: method toInstant()
location: variable now of type ZonedDateTime
1 error
1 warning


Is this normal? It seems that
javac
doesn't understand JDK classes with
-source
other than
1.8
.

According to javac,
javac
still supports various
-source release
options as previous releases did.

Supplement

I already know the JSR 310: Date and Time API is only available in Java 8. What does it matter with
javac
?

$ cat Java8.java
public class Java8 {
public void print(java.io.PrintStream out) {
out.printf("hello world\n");
}
}
$ javac Java8.java
$ cat Java7.java
public class Java7 {
public static void main(final String[] args) {
new Java8().print(System.out);
}
}
$ javac -source 1.7 -target 1.7 Java7.java
warning: [options] bootstrap class path not set in conjunction with -source 1.7
1 warning
$ java Java7
hello world


Conclusion

As @Eng.Fouad noted. The problem was that the method is a
default method
defined in an interface.
javac
seems to be catching that point.

$ cat Java8i.java
public interface Java8i {
default void print(java.io.PrintStream out) {
out.printf("hello world\n");
}
}
$ javac Java8i.java
$ cat Java8c.java
public class Java8c implements Java8i {
}
$ javac Java8c.java
$ cat Java7i.java
public class Java7i {
public static void main(final String[] args) {
new Java8c().print(System.out);
}
}
$ javac -source 1.7 -target 1.7 Java7i.java
warning: [options] bootstrap class path not set in conjunction with -source 1.7
Java7i.java:3: error: cannot find symbol
new Java8c().print(System.out);
^
symbol: method print(PrintStream)
location: class Java8c
1 error
1 warning


javac
should've told me more helpfully.

Answer

This is a new Time/Date API which is introduced in Java 8. That's why it does not compile with Java 7.

toInstant() is a default method, whereas -source 1.7 doesn't support default methods (Java 8's new feature).