Java 发布时不编译代码块?

Java 发布时不编译代码块?,java,eclipse,Java,Eclipse,我有许多行,我只是用来调试和帮助。有没有一种方法可以标记它们,使它们在发布项目时不会编译,但在Eclipse中运行/调试程序时仍然可以使用?更好的做法是将某个字段标记为“仅调试”,并在发布时完全放弃与该字段相关的所有内容 我知道,当使用这样的字段并在代码的关键部分使用这样的字段时,可能会遇到麻烦。但是我经常发现自己初始化了很多调试字段,然后注释掉它们,如果我不注释掉这些字段,就会导致错误 那么有没有更好、更有效的方法来处理这个问题呢?使用您最喜欢的记录器的跟踪级别,例如log4j。使用您最喜欢的

我有许多行,我只是用来调试和帮助。有没有一种方法可以标记它们,使它们在发布项目时不会编译,但在Eclipse中运行/调试程序时仍然可以使用?更好的做法是将某个字段标记为“仅调试”,并在发布时完全放弃与该字段相关的所有内容

我知道,当使用这样的字段并在代码的关键部分使用这样的字段时,可能会遇到麻烦。但是我经常发现自己初始化了很多调试字段,然后注释掉它们,如果我不注释掉这些字段,就会导致错误


那么有没有更好、更有效的方法来处理这个问题呢?

使用您最喜欢的记录器的跟踪级别,例如log4j。

使用您最喜欢的记录器的跟踪级别,例如log4j。

将您的代码放在另一个类中引用最终静态布尔值的
if
语句中。Java编译器没有编译像
if(DEBUG)
这样的
if
语句,它实际上表示
if(false)
(因为DEBUG是false)

public class Debug {
    public final static boolean DEBUG = true; // or false
}

public class X {
    public m() {
        if (Debug.DEBUG) {
             // Do some timing or displaying mouse positions, or whatever.
        }
    }
}
如果要验证这是否有效,可以使用
javap
反汇编程序:如果调试常量为
false
,编译器将不会生成代码,但如果调试常量为
true
,编译器将生成代码


为了进一步参考,(链接)中有一节关于条件编译,“示例13.4.9-2”。这就解释了我上面描述的内容。

将代码放在一个
if
语句中,该语句引用另一个类中的
最终静态布尔值
常量。Java编译器没有编译像
if(DEBUG)
这样的
if
语句,它实际上表示
if(false)
(因为DEBUG是false)

public class Debug {
    public final static boolean DEBUG = true; // or false
}

public class X {
    public m() {
        if (Debug.DEBUG) {
             // Do some timing or displaying mouse positions, or whatever.
        }
    }
}
如果要验证这是否有效,可以使用
javap
反汇编程序:如果调试常量为
false
,编译器将不会生成代码,但如果调试常量为
true
,编译器将生成代码


为了进一步参考,(链接)中有一节关于条件编译,“示例13.4.9-2”。这就解释了我上面所说的。

是的。使用日志框架

存在一个日志框架,允许开发人员将重要事件写入标准命令行、文件或他们想要的任何其他地方。Java附带了一个内置的(尽管是原始的)日志框架:
Java.util.logging

这是一个正在运行的示例

Logger logger = Logger.getLogger("foo-logger");

logger.log(Level.INFO, "This is a log statement at a rather standard logging level - use when you want to log information out.");
logger.log(Level.WARNING, "This is a log statement at a rather moderate logging level - use when things warrant looking into but aren't mission critical.");
logger.log(Level.SEVERE, "This is a log statement at a rather high logging level - use when an (often irrecoverable) error has occurred.");
如果您使用它,那么您将在终端中看到与此类似的内容:

Aug 23, 2014 10:05:24 AM com.stackoverflow.sandbox.Formatting main
INFO: This is a log statement at a rather standard logging level - use when you want to log information out.
Aug 23, 2014 10:05:24 AM com.stackoverflow.sandbox.Formatting main
WARNING: This is a log statement at a rather moderate logging level - use when things warrant looking into but aren't mission critical.
Aug 23, 2014 10:05:24 AM com.stackoverflow.sandbox.Formatting main
SEVERE: This is a log statement at a rather high logging level - use when an (often irrecoverable) error has occurred.

其他框架,例如,对于级别意味着什么更直观,并且提供了更简单的选项,可以在您想要的地方注销。

是的。使用日志框架

存在一个日志框架,允许开发人员将重要事件写入标准命令行、文件或他们想要的任何其他地方。Java附带了一个内置的(尽管是原始的)日志框架:
Java.util.logging

这是一个正在运行的示例

Logger logger = Logger.getLogger("foo-logger");

logger.log(Level.INFO, "This is a log statement at a rather standard logging level - use when you want to log information out.");
logger.log(Level.WARNING, "This is a log statement at a rather moderate logging level - use when things warrant looking into but aren't mission critical.");
logger.log(Level.SEVERE, "This is a log statement at a rather high logging level - use when an (often irrecoverable) error has occurred.");
如果您使用它,那么您将在终端中看到与此类似的内容:

Aug 23, 2014 10:05:24 AM com.stackoverflow.sandbox.Formatting main
INFO: This is a log statement at a rather standard logging level - use when you want to log information out.
Aug 23, 2014 10:05:24 AM com.stackoverflow.sandbox.Formatting main
WARNING: This is a log statement at a rather moderate logging level - use when things warrant looking into but aren't mission critical.
Aug 23, 2014 10:05:24 AM com.stackoverflow.sandbox.Formatting main
SEVERE: This is a log statement at a rather high logging level - use when an (often irrecoverable) error has occurred.

其他框架(如)更直观地了解级别的含义,并提供更简单的选项,让您可以随时注销。

为了调试目的,您添加了哪些字段?@Steinar Counters、string、timers。。。目前我正在屏幕上显示鼠标位置、世界位置和瓷砖坐标。这对我来说太棒了,我可能会添加更多的代码,这样我就可以打开和关闭它。然后我会添加更多这些东西来帮助我。但是,当我想发布一些东西时,我必须对所有内容进行注释。正如其他人所指出的,日志记录是最好和标准的选择。如果你想观察对象和内部字段,你也可以在调试时使用。为了调试目的,你添加了什么类型的字段?@Steinar Counters,string,timers。。。目前我正在屏幕上显示鼠标位置、世界位置和瓷砖坐标。这对我来说太棒了,我可能会添加更多的代码,这样我就可以打开和关闭它。然后我会添加更多这些东西来帮助我。但是,当我想发布一些东西时,我必须对所有内容进行注释。正如其他人所指出的,日志记录是最好和标准的选择。如果您想观察对象和内部字段,也可以在调试时使用。欢迎更全面一些。但我会研究它。日志由一个XML配置文件控制,您可以使用if(logger.isDebugEnabled())或if(logger.isTraceEnabled())来控制您想要的任何语句。在我使用Log4J2时,我从未显式检查日志是否处于调试模式。如果不是,则在该级别进行日志记录时不会写入任何内容。@Makoto当您编写logger.debug或logger.trace时,log4j会为您执行此操作。我指的是这样一种情况,即您只希望在调试时执行代码。我的印象是,这就是问题所在。我们欢迎更全面一点。但我会研究它。日志由一个XML配置文件控制,您可以使用if(logger.isDebugEnabled())或if(logger.isTraceEnabled())来控制您想要的任何语句。在我使用Log4J2时,我从未显式检查日志是否处于调试模式。如果不是,则在该级别进行日志记录时不会写入任何内容。@Makoto当您编写logger.debug或logger.trace时,log4j会为您执行此操作。我指的是这样一种情况,即您只希望在调试时执行代码。我的印象是,这就是问题所在。这是一个有趣的方法,但在出版之后,一切仍然存在。此外,如果我在循环外声明了字段,它们仍然会计入内存。不,不是,这就是为什么它被称为“条件编译”。当DEBUG等于
false
时,它在发布后就不存在了。真的,那么这就是行为