Java向后兼容性没有';行不通

Java向后兼容性没有';行不通,java,gradle,Java,Gradle,我已经创建了用于编码/解码属性文件的库。图书馆有两个主要用途: 对属性文件进行编码并将其保存到另一个文件 从编码文件返回键值(解码文件,将结果作为字符串存储在内存中,将字符串加载到Properties对象并从Properties对象返回结果) 一切似乎都很好,但今天我注意到这个库在Java1.5上不起作用。我注意到这个问题发生在解码端,所以让我们把重点放在这段代码上。假设负责解码的代码如下所示: String props = "key1=val1\nkey2=val2"; Properties

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

  • 对属性文件进行编码并将其保存到另一个文件
  • 从编码文件返回键值(解码文件,将结果作为字符串存储在内存中,将字符串加载到Properties对象并从Properties对象返回结果)
  • 一切似乎都很好,但今天我注意到这个库在Java1.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));
    
    我发现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:这是一个极好的发现,我甚至不知道/忘记这些东西的存在