Java是否具有像C#这样的"调试"和"发布"构建模式?

Jat*_*ing 42 .net c# java debugging release

在C#中,我们有2种模式建设项目:DebugRelease,不知Java有同样的事情.我使用IntelliJ IDEA作为Java IDE,到目前为止我还没有看到任何地方配置VS IDE中的构建模式.

Thi*_*ilo 34

javac 
  -g                         Generate all debugging info
  -g:none                    Generate no debugging info
  -g:{lines,vars,source}     Generate only some debugging info
Run Code Online (Sandbox Code Playgroud)

您可以选择在已编译的类中包含调试符号(这是默认值)或不执行此操作.不这样做没有多大好处.jar文件会稍微小一些,但性能优势很小(如果有的话).如果没有这些符号,则不再在堆栈跟踪中获取行号.您还可以选择包含具有局部变量名称的其他符号(默认情况下,只有源文件名和行号).

java
    -ea[:<packagename>...|:<classname>]
    -enableassertions[:<packagename>...|:<classname>]
                  enable assertions
Run Code Online (Sandbox Code Playgroud)

您还可以在运行时启用断言(默认为关闭),这在开发和测试期间有时很有用.这确实会对性能产生影响(如果有问题的代码确实使用了断言,我认为这种断言并不常见).

无论这些设置如何,JVM始终允许您附加调试器.

Java没有的是条件编译,其中根据某些外部设置编译完全不同的代码.你能得到的最接近的东西就像public static final boolean DEBUG_BUILD = true;代码中的某个地方,并在if语句中使用它.这实际上会使编译器排除无法访问的代码,但您必须在源代码中设置此常量.

  • @JatSing:不是直接的.您可以使用某种脚本在启动编译器之前更新该值.或者可能有一个Constants.java及其两个版本,并为其中一个设置编译类路径.但官方工具链中没有任何内容. (4认同)

Pet*_*rey 15

在Java中,通常的做法是释放所有内容,这是一种可以调试的方式.对于一些需要混淆的项目,他们可能有一个发布版本,但我在12年的Java开发中从未见过这一点.

断言和调试消息等事情通常在运行时为生产实例关闭,但如果需要,可以随时(甚至动态)打开.

恕我直言,最佳做法是在每个环境中使用相同的构建,而不仅仅是相同的源,而是相同的JAR.这为您提供了最好的机会,如果它在测试中起作用,它将在生产中工作,如果您在生产中遇到问题,您可以在测试中重新生成它.

由于以这种方式编写了如此多的Java代码,JIT非常擅长优化从未调用过的死代码.因此,恕我直言,大多数Java out out执行C++的微观"基准测试",当基准测试没有做任何事情并且JIT更好地检测到它时.恕我直言,C++假设开发人员足够聪明,不会编写不做任何事情的代码.

  • “我在开发Java的12年中从未见过这种情况”。对我来说,这是您答案中最相关的部分,因为您正在为HFT(!)编写Java。这是否意味着编译Java代码以包含所有调试信息不​​会干扰JVM JIT?我认为是,但请确认。 (3认同)
  • 对于未来的读者,“HFT”=“高频交易”。真正对性能敏感的东西:) (2认同)