2

我创建了用于编码/解码属性文件的库。图书馆有两个主要目的:

  1. 编码属性文件并将其保存到另一个文件。
  2. 从编码文件返回键值(解码文件,将结果作为字符串存储在内存中,将字符串加载到属性对象并从属性对象返回结果)。

一切似乎都运行良好,但今天我注意到该库不适用于 java 1.5。我注意到解码端出现了问题,所以让我们关注这段代码。假设负责解码的代码如下所示:

String props = "key1=val1\nkey2=val2";
Properties p = new Properties();
p.load(new StringReader(props));
p.list(System.out);

经过几次测试后,我发现问题出在这一行:

p.load(new StringReader(props));

我发现 java 1.5 中的 Properties 类没有load(Reader)声明。为了满足 java 1.5 API 要求,我将此行更改为load(InputStream). Everyting 现在工作正常,但这是问题所在。

我使用 gradle 编译项目,我知道这个库应该在 java 1.5+ 上运行(我的计算机上安装了 java 1.7)所以我在 build.gradle 中添加了这两行

sourceCompatibility = '1.5'
targetCompatibility = '1.5'

我认为 java 编译器会知道我想编译与 java 1.5 兼容的代码,并会显示适当的错误。为了确保这不是 gradle 问题,我从命令行编译了 java 代码,但结果相同(编译器没有显示任何错误)。那么为什么编译器在编译时不显示任何错误呢?

Java 1.5 属性类 API:http ://docs.oracle.com/javase/1.5.0/docs/api/java/util/Properties.html

Java 1.6 属性类 API:http ://docs.oracle.com/javase/6/docs/api/java/util/Properties.html

[更新]

既不-source-target不会检查 API 兼容性。如果是这样,我如何在 gradle 中检查它?正如millimoose 所写,maven 有这个插件(http://mojo.codehaus.org/animal-sniffer-maven-plugin/index.html)但是gradle 呢?

4

2 回答 2

4

请参阅 javac 文档中名为“交叉编译”和“交叉编译示例”的部分。

http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javac.html#crosscomp-options

具体这部分:

交叉编译时使用 -bootclasspath 和 -extdirs 很重要;参见下面的交叉编译示例.......使用新的引导类,这可能导致类文件在旧平台(在本例中为 Java SE 6)上不起作用,因为可以包含对不存在的方法的引用。

于 2013-09-12T12:42:14.387 回答
2

-source如果您使用指定版本不支持的语言结构,该开关仅指示编译器给出编译错误。例如,使用 try-with-resources-source 1.6会导致编译错误,因为它仅在 Java 7 及更高版本中受支持。它的使用更像是一种健全性检查(即:我的代码是否仍然与 Java 版本 1.x 兼容)

-target开关指示编译器发出与指定版本兼容的字节码。即:编译后的代码可以在指定版本的虚拟机上运行。

但是,这些开关都不会使编译器检查与早期 Java 版本的 Java 库的兼容性。-target 1.6这就是为什么从 Java 7 开始,如果您使用(或更早版本),编译器会发出警告,您还应该指定-bootclasspath指向该 Java 版本的 Java 运行时库集,以便它可以检查您的代码是否仅使用类和该Java版本的方法。

于 2013-09-12T12:48:10.573 回答