使用Java6来运行基于Java8开发的应用程序
因为有一项工作是修改以Java8开发的应用程序,使其能够在Java6环境下运行,我觉得这很不寻常,所以打算总结一下。
我觉得通常情况下是不会做这种事情的…
(而且我也不想做这样的工作哈哈)
背景:
我之前在另一个项目中使用过一个基于Restful的Java8应用程序,现在我想将该应用程序应用到我所在的项目中。但是,我发现该应用程序需要部署在Red Hat Enterprise Linux 5.1服务器上…
希望升级服务器的操作系统版本,但由于其他应用正在运行,所以不可能实现。
因此,必須將Java 8降級為Java 6。
据维基百科,红帽企业版Linux 5.1是在2007年11月7日发布的,已经有10年的历史了。
标准支持已经在2017年3月31日到期,因此已经结束标准支持期限。
但是延长支持期限已经延长至2020年11月30日。
Java8中的规范更改和新增
让我们来列举一些代表性的Java8新增功能。
-
- Lambda式
-
- メソッド参照
-
- Stream API
-
- Functional interfaces
-
- try-with-resources
-
- Interface Default,staticメソッド
- 日時API(LocalDateTimeなど)
除了这些之外,还添加了许多其他功能。请查看发布说明以了解详细信息。
Java8带来了很多API和写法的改变,对于Java来说,变化非常大。
Java回溯工具
Java回溯工具是一种用于将Java类文件从某个版本转换到旧版本的程序,本次使用了以下两个工具。
-
- Retrolambda
- streamsupport
逆向兰布达
RetroLambda是一个用于Maven和Gradle的插件,在构建时可以将Java8的代码转换为较低版本的代码。在构建后生成的class文件中,除了XXX.class之外,还会产生名为XXX$$Lambda$9.class的文件,这表明Java 8的Lambda表达式等代码是以单独的类文件进行处理的。
以下是Retrolambda所支持的内容。
-
- lambda式
-
- メソッド参照
-
- try-with-resources
- Interface Default,staticメソッド(限定サポート)
新的描述几乎全部都有相应的对应。
使用方法
在这里我们将解释Maven的使用方法。关于Gradle的使用方法请参考此处的ReadMe。
在pom.xml文件中按以下方式进行记录。
<plugin>
<groupId>net.orfjackal.retrolambda</groupId>
<artifactId>retrolambda-maven-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<goals>
<goal>process-main</goal>
<goal>process-test</goal>
</goals>
</execution>
</executions>
<configuration>
<target>1.6</target>
</configuration>
</plugin>
只需一种选项:在中国或中文中释义如下:
通过这个配置,Maven的生命周期将自动构建。configuration.target用于描述转换后的Java版本。
在开发时(如IDE设置)使用Java8 SDK进行开发,
并在Java6中执行构建的Jar文件。
这个方法的问题是即使使用Java8的API也可以编译通过(当然在运行时会出错),但似乎存在可以发出警告的插件。(我自己未使用过)
流媒体支持
streamsupport覆盖了许多Java 8的新API。
以下是被覆盖的内容。
-
- Streams API
-
- CompletableFuture API
-
- Parallel array operations
- Functional interfaces
用法
pom.xml -> POM文件
在pom.xml的dependencies中添加以下内容。
(streamsupport.version已在properties中定义。)
<!-- To use Java8 stream,functional API in Java6 -->
<dependency>
<groupId>net.sourceforge.streamsupport</groupId>
<artifactId>streamsupport</artifactId>
<version>${streamsupport.version}</version>
</dependency>
<dependency>
<groupId>net.sourceforge.streamsupport</groupId>
<artifactId>streamsupport-cfuture</artifactId>
<version>${streamsupport.version}</version>
</dependency>
<dependency>
<groupId>net.sourceforge.streamsupport</groupId>
<artifactId>streamsupport-flow</artifactId>
<version>${streamsupport.version}</version>
</dependency>
<dependency>
<groupId>net.sourceforge.streamsupport</groupId>
<artifactId>streamsupport-atomic</artifactId>
<version>${streamsupport.version}</version>
</dependency>
<dependency>
<groupId>net.sourceforge.streamsupport</groupId>
<artifactId>streamsupport-literal</artifactId>
<version>${streamsupport.version}</version>
</dependency>
基本用法
基本上,可以使用与Java 8 API不同的包名称来调用具有相同类名和相同方法名的类。
举个例子,CompletableFuture API的使用
import java.util.concurrent.CompletableFuture;
请下车。
import java8.util.concurrent.CompletableFuture;
变成这个样子。
Stream API的使用方法
可以使用RefStreams.of方法创建一个流实例。
import java8.util.stream.RefStreams;
RefStreams.of("a", "b", "c")
.map(String::toUpperCase)
.forEach(System.out::println);
在Java 8中,List类已经新增了stream方法,如下所示。
在这种情况下,将会是这样的。
import java.util.Arrays;
import java.util.List;
List<String> list = Arrays.asList("a", "b", "c");
list.stream()
.map(String::toUpperCase)
.forEach(System.out::println);
请将以下内容用中文进行同义表达(只需要一个选项):
↓
请将以下内容翻译成中文(只需要一个选项):
↓
import java.util.Arrays;
import java.util.List;
import java8.util.stream.StreamSupport;
List<String> list = Arrays.asList("a", "b", "c");
StreamSupport.stream(list)
.map(String::toUpperCase)
.forEach(System.out::println);
以下陈述是中文的,无需再进行翻译:
我祈祷读这篇文章的人不会遇到将Java8应用程序降级到Java6的机会…