JDK8 with -source 1.7 [Default Methods]

拟墨画扇 提交于 2019-12-10 12:44:41

问题


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.


回答1:


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




回答2:


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.



来源:https://stackoverflow.com/questions/22784030/jdk8-with-source-1-7-default-methods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!