在Java 6中使用Java 7 SDK特性

9
我希望在Java 7 SDK中使用一些NIO2功能,如果可用的话(具体来说是文件系统监视器),但我不想为Java 7编译我的类并排除Java 6运行时。主要是因为我想保持与Mac OS X的兼容性,也因为我不想强制用户升级。
这是否可能?最好的方法是什么?有任何链接或示例吗?
以下是我可以想象的一些方法:使用不同的编译器编译类文件,并根据Java版本动态加载它?还是使用反射?或者可能有一个编译器设置,用于生成Java 6兼容的类?
我正在寻找一个解决方案,不会变成丑陋的混乱 : ),所以理想情况下,我可以编写两个接口实现,一个使用新功能,一个不使用,然后动态选择一个而不必在所有地方进行反射调用。

由于我假设这些功能开始存在于SE7中,您认为如何能够以SE6兼容模式进行编译并保留它们? - KevinDTimm
我想要做的就是只在程序在Java 7运行时使用它们,如果不是,则回退到其他行为。请注意,我所说的是Java 7 SDK功能,而不是语言功能。 - Laurens Holst
抱歉,两个代码库是必要的(或者至少为每个环境创建一个单独的文件处理基础,并为每个版本创建单独的输出,因为在 X 版本编译的代码通常无法在任何较低版本中运行)。 - KevinDTimm
Java 6可以在Java 7虚拟机上运行(但据我所知反之则不行)。 - KevinDTimm
4个回答

9

只需使用 -target 1.6 进行构建,并组织您的代码,以便在使用 1.7 的模块周围干净地捕获 ClassNotFoundExceptions 和 NoClassDefFoundErrors。例如,可以使用单独的类加载器加载它们。


可以了,谢谢!我在Eclipse中配置了JDK 7来处理语法高亮,并使用目标Java 6进行构建。对于不存在的方法调用,你需要捕获NoSuchMethodError异常。 - Laurens Holst
@Laurens @EJP。我不明白,你怎么能用 -target 1.6 来构建源代码 1.7?这不会给你带来以下错误吗:javac: source release 1.7 requires target release 1.7 - Pacerier
@Pacerier 的诀窍是使用源代码 1.6 构建,而不是 1.7,并从 1.7 SDK 中调用方法。可能需要在编辑器中进行一些配置,以防止它抱怨并使代码完成工作,但除此之外,它就可以正常工作了。 - Laurens Holst
@Pacerier,我在哪里说到了-source 1.7?请指出来。 - user207421

1

如Toolkit所指出的那样,您可以轻松地构建Java 1.6。但是,您需要确保不会意外访问在Java 6中不存在的任何方法。这将导致生产代码中的运行时异常。

如果您正在使用Maven,则可以使用maven-enforcer-plugin,它可以确保没有Java 1.7类或方法调用潜入到为1.6构建的代码中。

一个例子是从Java 1.4到1.5的变化。我正在使用1.5构建目标为1.4的代码,并且我意外地使用了:

new BigDecimal(5);

这个编译很好,我也成功运行了。但是因为客户仍在使用1.4版本,所以失败了。因为这个构造函数在1.4中不存在,它是在1.5中引入的。

另一个解决方案是构建几个JAR文件,一个包含新的nio内容,一个包含旧的内容,并在安装时检测用户是否正在运行Java 1.7。如果是,则添加包含适当实现的JAR文件。


0

对于一些在Java 7中添加的元素,您可能会找到提供相应功能的Java 6 jsr jars。然而,我不认为这适用于文件系统监视器。


如果在Java 6上运行,我不需要这个功能,对于在Java 7上运行的用户来说是可选的。在这种特殊情况下,我可能会退回到轮询或显式刷新行为。 - Laurens Holst

0
关于文件系统监视器,在Java 7之前,我通常会每隔几秒钟轮询一次文件属性以检查它是否已更改。虽然不是很好,但实际上它几乎不使用任何可察觉的资源,并且从最终用户的角度来看,似乎工作方式相同。
如果您需要更全面的库,请查看http://commons.apache.org/jci/commons-jci-fam/index.html - 我认为它做了类似的事情,尽管我从未使用过。
我相当确定指定源1.7和目标1.6不起作用,我曾经因为另一个原因尝试过,从记忆中来看,JVM抱怨不兼容的标志(我猜测是因为7中的新invokedynamic)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接