Java9 jar兼容_Java9系列第三篇-同一个Jar支持多JDK版本运行

我计划在后续的一段时间内,写一系列关于java 9的文章,虽然java 9 不像Java 8或者Java 11那样的核心java版本,但是还是有很多的特性值得关注。期待您能关注我,我将把java 9 写成一系列的文章,大概十篇左右。

本文内容:在Java 9增强了JAR多版本字节码文件格式的支持,同一个Jar包可以包含多个Java版本的class文件。使用这个功能,我们可以将应用程序/库升级到新的Java版本,而不必强迫用户升级到相同的Java版本。

一、基本使用方法

多版本的字节码发行jar包,需要在其MANIFEST.MF中做以下的声明:

Multi-Release: true

复制代码

在jar包的META-INF/versions文件目录里面可以包含多个版本的class文件,编译结果目录结构如下:

jar root

- A.class

- B.class

- META-INF

- versions

- 9

- A.class

复制代码

假设上文中的根目录是使用java 8 或之前版本编译的字节码文件A.calss。META-INF/versions/9/是使用java 9 编写的java代码的编译结果A.class。

如果jar包是在JDK 8的运行时环境下运行,将使用根目录下面的class文件进行程序运行。

如果jar包是在JDK 9的运行时环境下运行,将使用META-INF/versions/9/下面的class文件进行程序运行。

假设未来这个项目升级JDK 10,决定在A.java中使用Java 10的一些新特性,可以单独针对A.class进行语法升级,并将编译结果a.class放置在META-INF/versions/10/下面

jar root

- A.class

- B.class

- META-INF

- versions

- 9

- A.class

- 10

- A.class

复制代码

现在,上面的jar包含了可以以三种Java版本运行的字节码文件,A.class兼容JDK 8、9、10。

二、真实的例子

java 8代码

下面的类文件代码我们让它运行在Java 8的环境下

package com.example;

public class IOUtil {

public static String convertToString(InputStream inputStream) throws IOException {

System.out.println("IOUtil 使用java 8 版本");

Scanner scanner = new Scanner(inputStream, "UTF-8");

String str = scanner.useDelimiter("\\A").next();

scanner.close();

return str;

}

}

复制代码

增加一个Main.java的应用程序入口文件,调用IOUtil.convertToString方法将InputStream转换成String。

package com.example;

public class Main {

public static void main(String[] args) throws IOException {

InputStream inputStream = new ByteArrayInputStream("测试字符串".getBytes());

String result = IOUtil.convertToString(inputStream);

System.out.println(result);

}

}

复制代码

Java 9代码

在Java 9 发布之后,我们决定使用Java 9 的新的语法重写IOUtil.convertToString方法。

package com.example;

public class IOUtil {

public static String convertToString(InputStream inputStream) throws IOException {

System.out.println("IOUtil 使用java 9 版本");

try (inputStream) { //Java9版本的增强try-with-resources

String str = new String(inputStream.readAllBytes());

return str;

}

}

}

复制代码

如上的代码所示,我们使用了Java 9的两个新特性带有inputStream引用的try-with-resource块和新的InputStream.readAllBytes()方法。

编译

将Java8 、Java9的IOUtil.java代码分别在JDK8、JDK9的版本下分别编译成class字节码文件,并将class文件按照如下的目录结构打成保存,并打jar包。(先按java8版本打成jar包,然后修改MANIFEST.MF文件,添加java 9字节码class文件即可)

D:\multi-release-jar-example\my-lib-jar>tree /A /F

+---com

| \---example

| IOUtil.class

| Main.class

|

\---META-INF

| MANIFEST.MF

|

\---versions

\---9

\---com

\---example

IOUtil.class

复制代码

运行 Main class

在JDK 9的环境下运行这个jar包

D:\multi-release-jar-example>java -cp my-lib.jar com.example.Main

IOUtil 使用java 9 版本

测试字符串

复制代码

在JDK 8的环境下运行这个jar包

D:\multi-release-jar-example>C:\jdk1.8.0_151\bin\java -cp my-lib.jar com.example.Main

IOUtil 使用java 8 版本

测试字符串

复制代码

欢迎关注我的博客,里面有很多精品合集

本文转载注明出处(必须带连接,不能只转文字):字母哥博客。

觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值