当前位置: 首页 > 知识库问答 >
问题:

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

厍书
2023-03-14

在Java是否可以像在C/C++中那样做一种#ifdef的事情?

示例:

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中的代码,即使它不会(也不应该)编译。

我正在寻找一种进行条件编译的方法--编译器甚至不应该查看if如果androidfalse

我的问题的上下文是,我在Eclipse中有一个处理应用程序。我在两个单独的项目中同时使用常规处理和Android处理,但我希望能够在没有编译器错误的情况下在彼此之间移动项目的源代码。例如,我希望能够拥有可以从Android项目转移到desktop项目的源代码文件,并且只需要更改几个东西--例如,将Android=true更改为Android=false

我真的需要它是条件编译,因为当我将源代码从Android项目复制到桌面项目时,桌面库显然不会包含Android库,然后源代码甚至不会编译。

编辑:所以现在我知道在Java没有预处理器,我的问题是:有没有其他的方法可以在我的项目中拥有这种功能(只需很小的改动就可以将源代码从一个复制到另一个),而不必手动注释特定的代码片段,也不必记住它们在哪里?

编辑2:这不是另一个问题的重复,因为我的问题包含可能有编译器错误的代码,而这个问题被关闭为一个重复的问题不是。(其他问题只涉及即使没有#ifdef也能很好地编译代码。)为了说明这一点,对于另一个问题,评价最高(也是被接受的)的答案是关于编译过的代码,但不是在字节码中发出的。然而,我的问题涉及的代码,甚至不会编译最初。

共有1个答案

鱼志诚
2023-03-14

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

但是,您可以通过隔离Android或桌面代码来解决问题。您可以通过在Eclipse中拥有三个单独的项目来实现这一点:

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

Android和Desktop项目都将在它们的类路径中包含核心项目。在eclipse中,您可以通过转到您的Java构建路径,然后单击Projects选项卡,然后将核心项目添加到“Required Projects”列表中来完成此操作。

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

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()都可以在任一平台上工作。但其思想是相同的:将您的项目拆分为多个项目,并使用接口抽象出在平台之间更改的行为。

 类似资料:
  • 在Gatling scala中是否有与以下代码相当的java代码?特别是wsAwait类: 这来自使用依赖关系gatling-http-2.3.1的scala项目示例。我和jar在io包中看到了。加特林。http。检查async特性AsyncCheckSupport扩展了AsyncCheckDSL。但这并没有包含在gatling-http-3.7.3中。jar在我的java测试项目中使用。 在最新

  • 我已经谷歌寻找解决方案,但我已经尝试了所有的方法,其中任何一个工作。首先,我的项目可以解决任何问题,后来我添加了一些更改,这就发生了。当我删除所有更改时,问题并没有消失。当我试图完成这个项目时,gradle控制台显示: Main.java:106:多个dex文件定义Lbolts/Aggregate Exception;com.android.dx.merge.DexMerger.readSorta

  • 我已经看了好几次留档了,看了来源,都没用。 我在寻找与PHPUnit的“this”相同的Codeception- 根据文档,就像这应该是可行的,但它不是“未定义的方法”。我必须激活哪个助手、模块或其他什么?

  • 我的问题很简单: 在我的每个textview中,我当前都使用属性 以提供一个华丽的外观后HC设备。 PS:不,我不想在资产文件夹里放一个字体,我只想用系统一。

  • 我是WPF技术的新手。我已经在WinForms开发了大约6年。 现在我想通过学习WPF来提高我的技能一大步。我正在阅读MSDN中的介绍指南,同时作为个人练习,我试图将WinForms UI的sructure转换为其WPF UI的等价物。 这是我想在WPF中重现的WinForms控件结构的简单模型: 我的问题:有人可以指导我或给我一个简短的例子,我如何可以添加一个下拉按钮的东西在工具栏?。