简体   繁体   English

条件Java编译

[英]Conditional Java compilation

I'm a longtime C++ programmer, new to Java. 我是一名长期从事Java的程序员。 I'm developing a Java Blackberry project in Eclipse. 我正在Eclipse中开发一个Java Blackberry项目。 Question - is there a way to introduce different configuration sets within the project and then compile slightly different code based on those? 问题 - 有没有办法在项目中引入不同的配置集,然后基于这些编译稍微不同的代码?

In Visual Studio, we have project configurations and #ifdef; 在Visual Studio中,我们有项目配置和#ifdef; I know there's no #ifdef in Java, but maybe something on file level? 我知道Java中没有#ifdef,但可能是文件级别的东西?

You can set up 'final' fields and ifs to get the compiler to optimize the compiled byte-codes. 您可以设置'final'字段和ifs以使编译器优化编译的字节代码。

...
public static final boolean myFinalVar=false;
...
if (myFinalVar) { 
 do something ....
 ....
}

If 'myFinalVar' is false when the code is compiled the 'do something....' bit will be missed out of the compiled class. 如果编译代码时'myFinalVar'为false,那么编译的类将遗漏'do something ....'位。 If you have more than one condition - this can be tidied up a bit: shift them all to another class (say 'Config.myFinalVar') and then the conditions can all be kept in one neat place. 如果您有多个条件 - 可以稍微整理一下:将它们全部转移到另一个类(比如'Config.myFinalVar')然后条件都可以保存在一个整洁的地方。

This mechanism is described in 'Hardcore Java'. 这种机制在'Hardcore Java'中描述

[Actually I think this is the same mechanism as the "poor man's ifdef" posted earlier.] [其实我认为这与早先发布的“穷人的ifdef”机制相同。]

you can manage different classpath, for example, implement each 'Action' in a set of distinct directories: 您可以管理不同的类路径,例如,在一组不同的目录中实现每个“Action”:

dir1/Main.java
dir2/Action.java
dir3/Action.java

then use a different classpath for each version 然后为每个版本使用不同的类路径

javac -sourcepath dir1 -cp dir2 dir1/Main.java

or 要么

javac -sourcepath dir1 -cp dir3 dir1/Main.java

If you want this specifically for BlackBerry, the BlackBerry JDE has a pre-processor : 如果你想专门用于BlackBerry,BlackBerry JDE有一个预处理器

You can enable preprocessing for your applications by updating the Eclipse™ configuration file. 您可以通过更新Eclipse™配置文件为应用程序启用预处理。

In C:\\Program Files\\Eclipse\\configuration\\config.ini, add the following line: osgi.framework.extensions=net.rim.eide.preprocessing.hook If you enable preprocessing after you have had a build, you must clean the project from the Project menu before you build the project again. 在C:\\ Program Files \\ Eclipse \\ configuration \\ config.ini中,添加以下行:osgi.framework.extensions = net.rim.eide.preprocessing.hook如果在进行构建后启用预处理,则必须清除在再次构建项目之前,从“项目”菜单中选择项目。

Then you can do things in the code like: 然后你可以在代码中做一些事情:

//#ifdef SOMETHING
// do something here
//#else
// do something else
//#endif

For details see Specifying preprocessor defines 有关详细信息,请参阅指定预处理器定义

In JDK6, you can do it by using Java's ServiceLoader interface. 在JDK6中,您可以使用Java的ServiceLoader接口来完成。 Check it here . 在这里查看

一个人可以称之为穷人的ifdefhttp//www.javapractices.com/topic/TopicAction.doifdef = ifdef

No, Java doesn't have an exact match for that functionality. 不,Java与该功能没有完全匹配。 You could use aspects, or use an IOC container to inject different implementation classes. 您可以使用方面,或使用IOC容器注入不同的实现类。

You could use maven's resource filtering in combination mit public static final fields, which will be indeed get compiled conditionally. 您可以在组合mit公共静态最终字段中使用maven的资源过滤,这将确实有条件地进行编译。

private static final int MODE = ${mode};

...

if (MODE == ANDROID) {
    //android specific code here
} else {

}

Now you need to add a property to your maven pom called "mode", which should be of the same value as your ANDROID constant. 现在你需要为你的maven pom添加一个名为“mode”的属性,它应该与你的ANDROID常量具有相同的值。

The java compiler should (!) remove the if and the else block, thus leaving your android code. java编译器应该(!)删除if和else块,从而留下你的android代码。

Not testet, so there is no guarantee and i would prefer configuration instead of conditional compilation. 不是testet,所以没有保证, 我更喜欢配置而不是条件编译。

You can integrate m4 into your build process to effectively strap an analogue to the C preprocessor in front of the Java compiler. 您可以将m4集成到构建过程中,以便有效地将类似物绑定到Java编译器前面的C预处理器。 Much hand-waving lies in the "integrate" step, but m4 is the right technology for the text processing job. 在“集成”步骤中挥舞着很多手,但m4是文本处理工作的正确技术。

Besides Maven, Ant and other build tools that provide similar functionality, one would rather build interfaces in Java and switch the implementations at Runtime. 除了Maven,Ant和其他提供类似功能的构建工具之外,人们宁愿在Java中构建接口并在运行时切换实现。
See the Strategy Pattern for more details 有关详细信息,请参阅策略模式

In opposite to C/C++ this will not come with a big performance penality, as Javas JIT-compiler optimizes at runtime and is able to inline this patterns in most cases. 与C / C ++相反,这不会带来很大的性能,因为Javas JIT编译器在运行时进行了优化,并且能够在大多数情况下内联这种模式。
The big pro of this pattern is the flexibility - you can change the underlying Implementation without touching the core classes. 这种模式的最大优点是灵活性 - 您可以在不触及核心类的情况下更改底层实现。

You should also check IoC and the Observer Pattern for more details. 您还应该检查IoC观察者模式以获取更多详细信息。

There are a couple of projects that bring support for comment-based conditional compilation to Java: 有几个项目支持基于注释的条件编译到Java:

Example in JPSG: JPSG中的示例:

/* with Android|Iphone platform */
class AndroidFoo {
  void bar() {
    /* if Android platform */
    doSomething();
    /* elif Iphone platform */
    doSomethingElse();
    /* endif */
  }
}

In eclipse you could use multiple projects 在eclipse中你可以使用多个项目

  • Main (contains common code) Main(包含通用代码)
  • Version1 (contains version1 code) 版本1(包含版本1代码)
  • Version2 (contains version2 code) 版本2(包含版本2代码)

    1. Main -> Select Project->Properties->Java Build Path->Projects tab Main - >选择Project-> Properties-> Java Build Path-> Projects选项卡
    2. Select Add... 选择添加...
    3. Add "Version1" xor "Version2" and OK back to the workspace. 添加“Version1”xor“Version2”并确定返回工作区。

Version1 and Version two contain the same files but different implementations. 版本1和版本2包含相同的文件但实现不同。 In Main you normally write eg 在Main中你通常会写例如

import org.mycustom.Version;

And if you included Version1/Version2 project as reference it will compile with the Version.java file from Version1/Version2 project. 如果您将Version1 / Version2项目作为参考包含在内,它将使用Version1 / Version2项目中的Version.java文件进行编译。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM