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.
A functional interface is an interface that contains only one abstract method. They can have only one functionality to exhibit. From Java 8 onwards, lambda expressions can be used to represent the instance of a functional interface. A functional interface can have any number of default methods.
Multiple Defaults With default functions in interfaces, there is a possibility that a class is implementing two interfaces with same default methods. The following code explains how this ambiguity can be resolved. First solution is to create an own method that overrides the default implementation.
Since Java8 static methods and default methods are introduced in interfaces. Unlike other abstract methods these are the methods can have a default implementation. If you have default method in an interface, it is not mandatory to override (provide body) it in the classes that are already implementing this interface.
A default method cannot override a method from java. lang. Object . The reasoning is very simple, it's because Object is the base class for all the java classes.
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).
This was produced because of a bug in javac. Related bugs are: JDK-8029240 and JDK-8030855. Both issues are already fixed. If you get a recent version of JDK8 or clone the last compiler version from langtools dev repo, you should be able to compile your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With