Подтвердить что ты не робот

Можете ли вы скомпилировать класс с использованием Java 8, а затем использовать его в Java 7?

Можно ли скомпилировать класс с использованием Java 8, а затем использовать его в Java 7?

Я хотел бы написать утилиту JAR с простым интерфейсом (совместимость с Java 7), но с использованием lambdas внутри. Затем я хотел бы использовать утилиту в некотором коде, который должен быть скомпилирован с помощью JDK 7..

Возможно ли это?


Как вы можете видеть, есть некоторые противоречивые ответы.. так, что правда?; -)

4b9b3361

Ответ 1

Вы можете использовать -source 1.7 -target 1.7 при компиляции с java 8 javac, чтобы сделать .classes, которые работают с java 7. Однако вы не получаете java 8-функций, таких как lambdas, тогда как вы должны использовать 1.7 в качестве исходного значения как хорошо.

Это не конец истории. В этом ответе было объяснено, что на самом деле нет новых инструкций JVM, поэтому это должно быть возможно. В этом ответе был введен инструмент retrolambda, который можно использовать для запуска java 8 на старых JVM. Автор утверждает, что этап компиляции не требуется, просто агент Java, преобразующий классы. Его решение касается только лямбда, а не каких-либо других функций. Конечно, это не принесет вам новых API-интерфейсов с java 8 или других улучшений, но, по крайней мере, это сделает то, что вы попросите. Некоторые из новых apis также были неофициально предоставлены, а именно java.util.stream и java.time.


Если бы мы были в пред-java8 эре, хотя -source 1.8 -target 1.7 не поддерживается javac, вы все равно можете использовать API компилятора, чтобы сделать то же самое. Также компилятор Eclipse смог это сделать, а также задачи ant и maven, которые используют один из двух указанных параметров (по умолчанию для компилятора-плагина используется javac). Это, похоже, уже не так прямолинейно, как использование других компиляторов, вам понадобятся реализации таких функций, как lambdas, а API компилятора будет использовать тот же "javac: source release 1.8 требует целевого релиза 1.8", поскольку другие.

Для заинтересованного, вот что происходит с этим путем, используя компилятор Eclipse и Maven и Пример кода калькулятора:

pom.xml:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>fi.eis.applications.java8</groupId>
  <artifactId>calculator</artifactId>
  <version>1.0-SNAPSHOT</version>
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.3</version>
        <configuration>
          <source>1.8</source>
          <target>1.7</target>
          <compilerId>eclipse</compilerId>
        </configuration>
        <dependencies>
          <dependency>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-compiler-eclipse</artifactId>
            <version>2.6</version>
          </dependency>
        </dependencies>
      </plugin>
    </plugins>
  </build>
</project>

Выполнение в Windows:

>mvn clean compile
[..snip..]
[INFO] BUILD SUCCESS
>cd target\classes

>"%JAVA_HOME%\bin\java.exe" Calculator
Exception in thread "main" java.lang.NoClassDefFoundError: java/lang/invoke/LambdaMetafactory
        at Calculator.main(Calculator.java:16)
Caused by: java.lang.ClassNotFoundException: java.lang.invoke.LambdaMetafactory
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 1 more

Таким образом, нужно было бы реализовать эти классы в чистом java в качестве сторонней библиотеки, чтобы заставить это работать.

Ответ 2

Невозможно, если вы скомпилируете вещи в новой версии Java, они не будут исполняться.

Ответ 3

Вы легко достигаете этого в maven pom.xml с плагином:

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
        <source>1.8</source>
        <target>1.7</target>
        <compilerArgument></compilerArgument>
    </configuration>
 </plugin>

как указано, что вы можете скомпилировать под 1.8 и 1.6, которые могут иметь лучшую совместимость с JavaSE 6