Java向后兼容性没有';行不通
我已经创建了用于编码/解码属性文件的库。图书馆有两个主要用途:Java向后兼容性没有';行不通,java,gradle,Java,Gradle,我已经创建了用于编码/解码属性文件的库。图书馆有两个主要用途: 对属性文件进行编码并将其保存到另一个文件 从编码文件返回键值(解码文件,将结果作为字符串存储在内存中,将字符串加载到Properties对象并从Properties对象返回结果) 一切似乎都很好,但今天我注意到这个库在Java1.5上不起作用。我注意到这个问题发生在解码端,所以让我们把重点放在这段代码上。假设负责解码的代码如下所示: String props = "key1=val1\nkey2=val2"; Properties
String props = "key1=val1\nkey2=val2";
Properties p = new Properties();
p.load(new StringReader(props));
p.list(System.out);
经过几次测试,我发现问题出在这条线路上:
p.load(new StringReader(props));
我发现Java1.5中的Properties类没有load(Reader)
声明。为了满足Java1.5API的要求,我将此行更改为load(InputStream)
。现在一切都很好,但问题是
我使用gradle来编译这个项目,我知道这个库应该在java 1.5+上工作(我的计算机上安装了java 1.7),所以我在build.gradle中添加了这两行代码
sourceCompatibility = '1.5'
targetCompatibility = '1.5'
我认为java编译器会知道我想要编译与Java1.5兼容的代码,并会显示相应的错误。为了确保这不是gradle问题,我从命令行编译了java代码,但结果相同(编译器没有显示任何错误)。那么为什么编译器在编译时不显示任何错误呢
Java 1.5属性类API:
Java 1.6属性类API:
[更新]
-source
或-target
都不会检查API兼容性。如果是这样,我如何在gradle登记正如millimoose所写,maven有这个插件(),但gradle怎么办?请参阅javac文档中名为“交叉编译”和“交叉编译示例”的部分
具体而言,本部分:
在以下情况下使用-bootclasspath和-extdirs是很重要的
交叉编译;请参见下面的交叉编译示例。。。。。。。如果你不
指定引导类的正确版本,编译器将
使用旧的语言规则(在本例中,它将使用1.6版
与新的引导程序相结合
类,这可能导致类文件无法在旧版本上工作
平台(在本例中为JavaSE6),因为引用不存在
方法可以包括在内
如果使用指定版本不支持的语言构造,则
-source
开关仅指示编译器给出编译错误。例如,在-source 1.6
中使用try-with-resources将导致编译错误,因为它仅在Java 7及更高版本中受支持。它的用途更多的是一种健全性检查(即:我的代码是否仍然与Java 1.x版兼容)
-target
开关指示编译器发出与指定版本兼容的字节码。即:编译后的代码可以在指定版本的虚拟机上运行
但是,这两个开关都不会使编译器检查与早期Java版本的Java库的兼容性。这就是为什么自Java 7以来,如果使用
-target 1.6
(或更早版本),编译器会发出警告,您还应该指定-bootclasspath
以指向该Java版本的Java运行时库集,以便它可以检查您的代码是否仅使用该Java版本的类和方法。无论-source
还是-target
都不要检查您是否使用给定JDK版本中不存在的API方法。有一个Maven插件可以做到这一点:好的,但是如何防止这种情况?在编译过程中我需要使用不同的jdk版本吗?要么使用Maven插件,要么使用不同的jdk,是的。谢谢,我使用gradle,所以我会尝试为它找到合适的插件。顺便问一下,使用-source
和-target
有什么意义?target:因为每个新的JDK版本都引入了新的字节码版本。旧JVM无法以新格式运行代码。来源:因为偶尔会引入新的语言特性,而新的语言特性在旧的JVM上不起作用。源代码选项阻止您使用更新的语言功能。+1:这是一个极好的发现,我甚至不知道/忘记这些东西的存在