Java等效的#ifdef,允许不可编译的代码

时间:2013-10-30 13:51:17

标签: java android c eclipse processing

在Java中是否可以做一些#ifdef的事情,比如在C / C ++中?

示例:

class Test
{
    public static final boolean ANDROID = false;

    public Test()
    {
        if (ANDROID)
        {
            // do stuff that won't compile if not on android
        }
        else
        {
            // do stuff that should be only done on desktop
        }
    }
}

请注意,即使ANDROIDfalse,如示例所示,它仍会尝试编译if内的代码,即使它不会(并且不应该) 't)编译。

我正在寻找一种方法来进行条件编译 - 如果ifANDROID,编译器甚至不应该在false外观

我的问题的背景是我在Eclipse中有一个Processing应用程序。我在两个单独的项目中使用Android的正常处理和处理,但我希望能够在没有编译器错误的情况下将项目的源代码移动到彼此之间。例如,我希望能够拥有可以从Android项目移动到桌面项目的源代码文件,只需更改一些内容 - 例如,将ANDROID = true更改为{{1} }。

我真的需要它进行条件编译,因为当我将源代码从Android项目复制到桌面项目时,桌面库显然不会包含Android库,然后源代码甚至不会编译。 / p> 编辑:所以现在我知道Java中没有预处理器,我的问题是:在我的项目中是否还有其他方法可以将源代码从一个复制到另一个只有非常小的更改),而不必手动[取消]注释特定的代码片段,并记住它们的位置?

编辑2:这不是另一个问题的重复,因为我的问题包括可能在其中存在编译器错误的代码,而关闭它作为副本的问题却没有。 (另一个问题只涉及即使没有ANDROID = false也能正常编译的代码。)为了解释,另一个问题的评价最高(和接受)的答案是关于编译的代码 ,但在字节码中根本不是发射。但是,我的问题涉及最初甚至无法编译的代码。

5 个答案:

答案 0 :(得分:3)

由于Java本身并不包含预处理器,因此您需要在编译之前手动执行一个预处理器。 c预处理器是m4,你可以自己运行。

答案 1 :(得分:2)

正如其他人所说,你实际问题的答案是否定的。

但是,您可以通过隔离Android或桌面代码来解决问题。你可以通过在eclipse中有三个独立的项目来做到这一点:

  • 核心:这是"共享"两个版本之间存在的代码。
  • Android:这只包含在Android上运行的代码。
  • 桌面:仅包含在桌面上运行的代码。

您的Android和Desktop项目都会在其类路径中包含Core项目。在eclipse中,您可以通过转到Java Build Path,然后单击Projects选项卡,然后将Core项目添加到" Required项目"列表。

然后,您需要设置代码,以便Android和桌面项目实际部署,并且您的Core项目包含它们之间共享的代码。这是一个简单的例子。我们假设我们有一个如下所示的示例类:

public class Adder{
   public void addAndPrint(int x, int y){

      //code that will work on both Android and desktop
      int sum = x+y;

      if (ANDROID){
         //code that will only work on Android
         Log.v("example", "Sum:" + sum);
      }
      else{
         //code that will only work on desktop
         System.out.println("Sum: " + sum)
      }
   }
}

你可以通过重构代码来隔离"核心"适用于桌面和Android的代码。像这样:

//example core class
public class CoreAdder{

   Printer printer;

   public CoreAdder(Printer printer){
      this.printer = printer;
   }

   public void addAndPrint(int x, int y){
      int sum = x+y;
      printer.print("Sum: " + sum);
   }
}

//example core interface. We might print differently on
//Android and Desktop, so implement this interface in each.
public interface Printer{
   public void print(String printMe);
}

然后,您将隔离仅适用于桌面的代码:

//on desktop, use System.out.println()
public class DesktopPrinter implements Printer{
   public void print(String printMe){
      System.out.println(printMe);
   }
}

//on desktop, entry point is main()
public class DesktopMain{
   public static void main(String... args){
      DesktopPrinter printer = new DesktopPrinter();
      CoreAdder adder = new CoreAdder(printer);
      adder.addAndPrint(1, 2);
   }
}

只适用于Android的代码:

//on Android, use a logger
public class AndroidPrinter implements Printer{
   public void print(String printMe){
      Log.v("example", "index=" + i);
   }
}

//on Android, entry point is Activity
public class AndroidActivity extends Activity{

   public void onCreate(Bundle savedInstanceState) {
      AndroidPrinter printer = new AndroidPrinter ();
      CoreAdder adder = new CoreAdder(printer);
      adder.addAndPrint(1, 2);
   }
}

请注意,这只是一个示例,我知道System.out.println()Log.v()都可以在任一平台上运行。但这个想法是一样的:将项目分成多个项目,并使用接口抽象出平台之间变化的行为。

答案 2 :(得分:1)

在Java中没有预处理器,如C,C ++等。你所能做的就是注释掉代码。

答案 3 :(得分:0)

不,Java中没有可以隐藏代码块到JVM的预处理器。

编辑: 虽然你当然可以针对你的代码库运行任何程序来预处理它,但想想你是否真的想要它。 Android代码会及时与其他Java代码分歧,您的代码将会被那些#ifdef类似的语句所困扰。您的IDE仍然会看到它们并在两个代码区域中给您错误。在这种情况下,仅仅制作两个项目就更容易了,或者,这就是我的建议,创建一个独立于平台的库,您可以在两个项目中包含这些库,并包含您需要的功能。

答案 4 :(得分:0)

在C中使用#ifdef和朋友,并在编译之前通过C预处理器运行Java源代码。

对于gcc,预处理器称为cpp,对于VC,它使用选项/P的cl.exe。