Java 7编译的Jar包能否作为Java 6兼容项目的Maven依赖(无源码)?
Java 7编译Jar包作为Java 6项目依赖的问题解答
咱们一个个把这两个问题掰明白,这都是Java版本兼容里的常见坑,尤其你手里只有编译好的Jar包、没法改源码的情况下,得把这些情况说透。
1. 能否将Java 7编译的Jar包作为编译目标为Java 6的项目的依赖?
先明确下:“编译目标为Java 6”指的是你的项目用javac -target 1.6(或者Maven里配置maven.compiler.target=1.6)编译,产出Java 6兼容的字节码。
这里得分编译阶段和运行阶段来看:
- 编译阶段:如果你的项目代码没有调用这个Jar里任何Java 7新增的API(比如
java.nio.file下的类、和try-with-resources语法相关的实现),那编译大概率能通过——因为Java编译器只检查你调用的方法/类的元数据是否存在,不会管依赖Jar的字节码版本。但如果你的代码用到了Jar里依赖Java 7的API,编译时就会直接报错,因为Java 6编译器根本不认识这些新东西。 - 运行阶段:不管编译过没过,只要你在Java 6的JVM上运行,加载这个Jar里的类时肯定会抛出
UnsupportedClassVersionError——因为Java 7编译的字节码版本是51,而Java 6的JVM只支持最高版本50的字节码,根本认不出这个Jar的类文件。
所以结论是:编译可能侥幸通过,但运行时完全无法在Java 6环境下工作,不建议这么做。
2. 能否将Java 7编译的Jar包作为兼容Java 6的项目的依赖?
这里的“兼容Java 6”应该是指你的项目最终要能在Java 6的JVM上稳定运行对吧?
答案是:基本不行,除非这个Jar是特殊情况编译的。
- 如果这个Jar是Java 7默认编译的(字节码版本51),那不管你的项目怎么配置兼容Java 6,只要在Java 6的JVM上运行,一加载这个Jar的类就会报错,根本启动不起来。就算你用高版本JVM跑,那你的项目也没法在Java 6环境下使用,完全违背了“兼容Java 6”的初衷。
- 唯一的例外是这个Jar其实是用Java 7编译器,但指定了
-target 1.6、-source 1.6甚至-bootclasspath指向Java 6的rt.jar编译出来的——这种情况Jar的字节码版本是50,本质是Java 6兼容的,只是用了Java 7的编译器而已,严格来说不算“Java 7编译的Jar”(通常说的Java7编译Jar指默认字节码版本51)。
另外补充:如果你只有这个Jar没有源码,想让它兼容Java 6几乎没有靠谱的办法——虽然有一些字节码降级工具(比如RetroGuard、ProGuard)能尝试把字节码版本从51降到50,但还要手动处理掉Jar里用到的Java 7特有API和语法,操作难度极大,很容易出各种奇奇怪怪的Bug,不推荐。
内容的提问来源于stack exchange,提问作者de_xtr
相关产品推荐
相关产品推荐

