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

2022-09-01 00:07:06

在C#中,我们有2种模式来构建项目:和,我想知道Java是否有同样的东西。我正在使用IntelliJ IDEA作为Java IDE,到目前为止,我还没有看到任何地方像VS IDE那样配置构建模式。DebugRelease


答案 1
javac 
  -g                         Generate all debugging info
  -g:none                    Generate no debugging info
  -g:{lines,vars,source}     Generate only some debugging info

您可以选择在已编译的类中包含调试符号(这是默认设置),也可以选择不这样做。不这样做没有多大好处。jar 文件会小一些,但性能优势很小(如果有的话)。如果没有这些符号,您将不再在堆栈跟踪中获得行号。您还可以选择使用局部变量名称包括其他符号(默认情况下,只有源文件名和行号)。

java
    -ea[:<packagename>...|:<classname>]
    -enableassertions[:<packagename>...|:<classname>]
                  enable assertions

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

无论这些设置中是否有任何设置,JVM 始终允许您附加调试器。

Java没有的是条件编译,其中完全不同的代码将基于某些外部设置进行编译。您可以获得的最接近的是类似于代码中的某个位置的东西,并在if语句中使用该内容。这实际上会使编译器排除无法访问的代码,但您必须在源代码中设置此常量。public static final boolean DEBUG_BUILD = true;


答案 2

在Java中,发布所有内容是一种可以调试的正常做法。对于一些需要混淆的项目,它们可能有一个发布版本,但我在开发Java的12年里从未见过这种情况。

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

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

由于很多Java代码都是以这种方式编写的,因此JIT非常擅长优化从不调用的死代码。如此之多,以至于恕我直言,Java输出执行的大多数微“基准测试”C++,都是当基准测试不做任何事情并且JIT更好地检测这一点时。恕我直言,C++假设开发人员足够聪明,不会编写不做任何事情的代码。