Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 936
Jin Kwon Avatar asked Apr 01 '14 11:04

Jin Kwon


People also ask

Can functional interface have default methods?

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.

Can an interface have multiple 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.

Can classes have default methods?

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.

Can you override default methods?

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.


2 Answers

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

like image 119
Eng.Fouad Avatar answered Oct 21 '22 23:10

Eng.Fouad


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.

like image 33
Vicente Romero Avatar answered Oct 22 '22 01:10

Vicente Romero