在Java(Eclipse)中调试和发布构建?

在Java(Eclipse)中调试和发布构建?,java,debugging,conditional-compilation,Java,Debugging,Conditional Compilation,不熟悉Java和Eclipse(但熟悉Visual Studio和Delphi)。使用EclipseMars(4.5)时,无法找到如何设置构建配置(调试或发布)。两个相关问题: Java是否支持调试/发布 如何在这两种配置之间切换 您能否在构建时检测配置并运行如下条件代码(以Delphi为例): {$IFDEF DBG}CallDebugFunction();{$ELSE}CallReleaseFunction();{$ENDIF} java不完全支持调试/发布。但有一些事实值得记住,还有一些

不熟悉Java和Eclipse(但熟悉Visual Studio和Delphi)。使用EclipseMars(4.5)时,无法找到如何设置构建配置(调试或发布)。两个相关问题:

  • Java是否支持调试/发布
  • 如何在这两种配置之间切换
  • 您能否在构建时检测配置并运行如下条件代码(以Delphi为例):
    {$IFDEF DBG}CallDebugFunction();{$ELSE}CallReleaseFunction();{$ENDIF}

    • java不完全支持调试/发布。但有一些事实值得记住,还有一些其他方法可以完成同一件事的某些部分

      java的创造者认为,让每个编译单元产生完全相同的字节码,而不考虑外部因素,这是一个巨大的优点,因此java没有预处理器

      java最接近您熟悉的调试/发布类型是
      assert
      关键字。您可以通过向VM提供
      -assertionEnabled
      -ea
      )参数来控制是否评估断言。阅读它,并了解如何将参数传递给VM

      请注意,VM参数是运行时参数,它们与编译器无关,这意味着编译器将始终将断言发送到字节码中,如果您不提供
      -ea
      ,则运行时将避免对它们进行计算。因此,对于每个断言,至少始终会有一个隐藏的
      if(assertionEnabled){…}
      语句来执行

      另一件值得记住的事情是,
      publicstaticfinal
      变量被视为编译时常量,编译器可以避免为受
      if(false)
      子句控制的源代码发出任何字节码。然而,源代码总是被编译的,所以它必须是正确的,尽管不会生成字节码

      因此,您可以将一个全局变量定义为
      publicstaticfinalbooleandebug=true
      ,以控制所有调试代码,但您必须在源代码中手动更改它,并重新生成项目,以生成发布版本;java明确禁止提供任何其他实现这一点的方法

      另外,请注意,
      if(false)
      (扩展为
      if(DEBUG)
      )将产生一个关于条件始终为true或始终为false的警告,因此我不喜欢使用它

      java的理念是,我们通常不太在意性能,以至于不想完全控制调试和发布之间微小的性能差异。一般来说,
      assert
      关键字就是所需要的,事实上(令我失望的是),大多数java用户甚至因为各种原因(lame,IMHO)而不使用assert

      至于发出调试信息,绝大多数调试信息都是生成的,因为它必须通过反射在运行时可用。我知道有一件小事你可以控制:
      -parameters
      编译器选项,但它实际上是无关紧要的,而且编译器的未来版本可能会反对该选项,并将其控制的功能作为标准行为包含在内

      这也意味着Java代码可以比C++代码更容易地被逆向工程,因此,存在java java混淆器,它在将java代码发送到Java编译器之前通过标识符的阶段来传递代码,从而减少字节码文件中有用的信息量。 您可能很高兴知道,由于JITting,这一切都不算太糟糕:字节码由VM编译成机器代码,并且在该阶段执行了许多优化,因此您总是从中受益,而不仅仅是在发布时

      至于检测是否启用了断言,可以使用以下代码:

      static boolean areAssertionsEnabled()
      {
          //noinspection UnusedAssignment
          boolean b = false;
          //noinspection ConstantConditions,AssertWithSideEffects
          assert b = true;
          //noinspection ConstantConditions
          return b;
      }
      

      noinspection
      thingies用于抑制IntellijIDEA中的警告,IntellijIDEA是一种远远优于Eclipse的java IDE。如果您坚持使用Eclipse,您将必须为它找到等效的警告抑制机制。

      编译器选项(如用于控制生成调试信息的
      -g
      系列)如何?我修改了我的答案。这解释了为什么我无法在Visual Studio和Delphi中找到您面临的选项!我习惯于调试/发布(并发现它们很有用)…但我可以很容易地习惯Java方式。回答得好,谢谢。