Java:包装Java 1.5和1.6代码的最简单方法

我想打包一段绝对必须在Java 1.5上运行的代码。 如果VM是1.6 VM,则代码的一部分可以“增强”程序。

基本上这是这个方法:

private long[] findDeadlockedThreads() { // JDK 1.5 only supports the findMonitorDeadlockedThreads() // method, so you need to comment out the following three lines if (mbean.isSynchronizerUsageSupported()) return mbean.findDeadlockedThreads(); else return mbean.findMonitorDeadlockedThreads(); } 

什么是最简单的方法在1.5上进行编译 ,然后在1.6时进行1.6方法调用

在过去,我通过编译一个独特的1.6类来做类似的事情,我将使用我的应用程序打包并在1.6上使用ClassLoader实例化(因为1.6 JVM非常适合混合0x32和0x31类),但我认为这是一个有点矫枉过正(有点痛苦,因为在构建过程中你必须构建0x31和0x32 .class文件)。

如果我想在1.5上编译上述方法,我该怎么办? 也许使用reflection然后如何(我对reflection我根本不熟悉)

注意:如果你很好奇,上面的方法来自这篇文章: http : //www.javaspecialists.eu/archive/Issue130.html

(但我不想像在文章中那样“评论三行”,我想要在1.5和1.6上编译和运行)

你不能在1.5上编译它,但你可以在1.6上编译,目标选项设置为1.5(这将产生1.5的字节代码),并在代码中使用reflection来查明方法是否可用。

此代码将查找方法:mbean.getClass()。getMethod(“findDeadlockedThreads”,new Class [0]); 问题是,如果该方法不存在而不是简单地返回null或类似的东西,它会抛出NoSuchMethodException。 这意味着,你需要这样的代码:

 try { mbean.getClass().getMethod("findDeadlockedThreads", new Class[0]); return mbean.findDeadlockedThreads(); } catch(NoSuchMethodException ex) { return mbean.findMonitorDeadlockedThreads(); } 

这不是很好,因为它使用Exception来做出决定。 那可能不是很快。 另一种方法是使用getMethods,并在方法可用时迭代返回的列表。 那也不是很快。

编辑:克里斯托弗Oezbek建议在评论中只检查方法的存在一次,并保存结果,以避免Try-catch块的开销。 这是正确的,也是一个很好的解决方案。 matt b警告,如果在Java 1.5下使用的类和方法,Java-Compiler的target-option不会检查。 这是正确的(否则它将无法工作,因为您希望针对1.6方法进行编译)这意味着,应该在1.5-VM下仔细测试该程序,以避免此问题。 感谢您对我们的评论。

编译为1.5。

在您的代码中使用reflection。 您可以从Class接口获取Method对象; 它有一个invoke方法,它将您的mbean实例作为参数。 像这样的东西:

类c = mbean.getClass(); //也可以使用YourClass.class来获取它

方法m = c.getMethod(“findMonitorDeadLockedThreads”); //或任何其他方法(方法的参数使用Class …第二个参数指定给getMethod)

m.invoke(mbean)//用你的实例调用Method

当然,你不必每次都这样做; 在构造函数中设置Method引用,然后根据需要调用正确的引用。

Maven让您可以使用配置文件轻松完成此操作。 配置文件背后的想法是,您希望根据某些条件构建两种不同版本的东西。 在此特定示例中,您可以定义jdk15jdk16配置文件,指定要使用哪个JDK版本进行编译,并告诉它在jdk15配置文件中包含该类的一个副本,另一个在jdk16中包含该副本。

要开始使用,请参阅:

http://unserializableone.blogspot.com/2008/09/compile-and-test-with-different-jdk.html

这描述了如何解决问题的不同JDK版本部分。

要处理问题的第二部分,根据JDK版本使用不同的类定义,请参阅:

Maven – 在构建时包含不同的文件