java 条件编译_Java条件编译:如何防止代码块被编译?

Java条件编译:如何防止代码块被编译?

我的项目需要Java 1.6进行编译和运行。 现在,我有一个要求使其与Java 1.5一起使用(从市场营销方面)。 我想替换方法主体(返回类型和参数保持相同),以使其在Java 1.5中编译时没有错误。

详细信息:我有一个名为ifdef, ifndef的实用程序类,它封装了所有特定于OS的内容。 它有一种方法

public static void openFile(java.io.File file) throws java.io.IOException {

// open the file using java.awt.Desktop

...

}

打开文件,就像双击一样(ifdef, ifndef Windows命令或hasattr Mac OS X命令等效项)。 由于无法使用Java 1.5进行编译,因此我想在编译期间将其排除,并替换为另一种方法,该方法使用2744943626802430430980(对于Windows而言为2744943626802430430979,对于Mac OS X是为2744943626802802430979)。

问题:我该怎么做? 注释可以在这里提供帮助吗?

注意:我使用ant,我可以制作两个java文件2744943626802430430和hasattr,其中将包含#+feature978类和Java 1.5和1.6所需的代码,然后在编译之前将其中一个复制到OS.java(或采用难看的方式-替换其中的内容)。 OS.java有条件地取决于Java版本),但如果有另一种方法,我也不想这样做。

详细说明:在C中我可以使用ifdef, ifndef,在Python中没有编译,并且可以使用hasattr或其他功能检查功能,在Common Lisp中,我可以使用#+feature。Java是否有类似的东西?

找到了这篇文章,但似乎没有帮助。

任何帮助是极大的赞赏。 kh。

9个解决方案

43 votes

不,Java不支持条件编译。

通常的计划是将应用的特定于操作系统的位隐藏在OS*之后,然后在运行时检测操作系统类型,并使用-source 1.5 -target 1.5加载实现。

在您的情况下,您没有理由不能同时使用Java 1.6和-source 1.5 -target 1.5编译两个2744944307168871871(并影响整个应用程序),然后在工厂方法中获取OS类(现在将是接口)检测到2744944307168871871427 类可用,并加载正确的版本。

就像是:

public interface OS {

void openFile(java.io.File file) throws java.io.IOException;

}

public class OSFactory {

public static OS create(){

try{

Class.forName("java.awt.Desktop");

return new OSJ6();

}catch(Exception e){

//fall back

return new OSJ5();

}

}

}

Gareth Davis answered 2020-02-12T23:12:29Z

18 votes

在Gareth建议的接口后面隐藏两个实现类可能是最好的方法。

就是说,您可以使用ant build脚本中的replace任务引入一种条件编译。 诀窍是在代码中使用注释,这些注释将在编译源代码之前通过文本替换打开/关闭,例如:

/*{{ Block visible when compiling for Java 6: IFDEF6

public static void openFile(java.io.File file) throws java.io.IOException {

// open the file using java.awt.Desktop

...

/*}} end of Java 6 code. */

/*{{ Block visible when compiling for Java 5: IFDEF5

// open the file using alternative methods

...

/*}} end of Java 5 code. */

现在在ant中,当您针对Java 6进行编译时,将“ IFDEF6”替换为“ * /”,得到:

/*{{ Block visible when compiling for Java 6: */

public static void openFile(java.io.File file) throws java.io.IOException {

// open the file using java.awt.Desktop

...

/*}} end of Java 6 code. */

/*{{ Block visible when compiling for Java 5, IFDEF5

public static void openFile(java.io.File file) throws java.io.IOException {

// open the file using alternative methods

...

/*}} end of Java 5 code. */

在为Java 5进行编译时,请替换“ IFDEF5”。 请注意,在/*{{、/*}}块内部使用2744944878288281280时要小心。

rsp answered 2020-02-12T23:13:03Z

7 votes

下面介绍的Ant脚本提供了简洁的技巧。

链接:[https://weblogs.java.net/blog/schaefa/archive/2005/01/how_to_do_condi.html]

例如

//[ifdef]

public byte[] getBytes(String parameterName)

throws SQLException {

...

}

//[enddef]

用Ant脚本

请转到上面的链接以获取更多详细信息。

Youngjae answered 2020-02-12T23:13:40Z

5 votes

您可以使用反射进行调用,并使用Java 5编译代码。

例如

Class clazz = Class.forName("java.package.ClassNotFoundInJavav5");

Method method = clazz.getMethod("methodNotFoundInJava5", Class1.class);

method.invoke(args1);

您可以捕获任何异常,然后退回到适用于Java 5的东西。

Peter Lawrey answered 2020-02-12T23:14:09Z

5 votes

我不是一个出色的Java专家,但似乎Java中的条件编译受支持并且易于实现。 请阅读:

[http://www.javapractices.com/topic/TopicAction.do?Id=64]

引用要点:

有条件的编译实践用于有选择地从类的编译版本中删除代码块。 它利用编译器将忽略任何无法访问的代码分支这一事实。   要实施条件编译,

将静态的最终布尔值定义为某个类的非私有成员

将在有条件的if块中编译的位置代码,该块评估布尔值

将布尔值设置为false以使编译器忽略if块; 否则,保持其值为真实

当然,这使我们可以“编译”任何方法中的代码块。 要删除类成员,方法甚至整个类(可能只剩下一个存根),您仍然需要一个预处理器。

gregko answered 2020-02-12T23:15:01Z

5 votes

在Java 9中,可以创建多版本的jar文件。 本质上,这意味着您需要制作同一Java文件的多个版本。

编译它们时,将使用所需的jdk版本编译Java文件的每个版本。 接下来,您需要将它们打包成如下所示的结构:

+ com

+ mypackage

+ Main.class

+ Utils.class

+ META-INF

+ versions

+ 9

+ com

+ mypackage

+ Utils.class

在上面的示例中,代码的主要部分是用Java 8编译的,但是对于Java 9,还有Utils类的其他(但不同)版本。

在Java 8 JVM上运行此代码时,它甚至不会检查META-INF文件夹中的类。 但是在Java 9中,它将并且将找到并使用该类的最新版本。

bvdb answered 2020-02-12T23:15:35Z

4 votes

如果您不希望在应用程序中有条件地启用代码块,那么预处理器是唯一的方法,您可以看看可用于maven和ant项目的java-comment-preprocessor。

ps。

我也举了一些例子,说明如何在Maven中使用预处理功能来构建JEP-238多版本JAR,而无需复制源

Igor Maznitsa answered 2020-02-12T23:16:04Z

1 votes

Manifold框架中有一个新的Java预处理器。 这是一个javac插件,这意味着它直接与Java编译器集成在一起-没有构建步骤,没有代码生成目标等要管理。

Axk2g.png

Scott answered 2020-02-12T23:16:24Z

0 votes

Java Primitive Specializations Generator支持条件编译:

/* if Windows compilingFor */

start();

/* elif Mac compilingFor */

open();

/* endif */

该工具具有Maven和Gradle插件。

leventov answered 2020-02-12T23:16:48Z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值