在调试一些Java代码(Log4J 2.5)时,我看到了一个无法解释的奇怪行为。

在呈现Log4J日志消息的过程中,构造了Log4jLogEvent对象:

public LogEvent createEvent(String loggerName, Marker marker, String fqcn, Level level, Message data, List<Property> properties, Throwable t) {
    return new Log4jLogEvent(loggerName, marker, fqcn, level, data, properties, t);
}


Log4jLogEventgrepcode)的符号
是一种简单的方法,它将给定的参数分配给新构造的对象字段:

private Log4jLogEvent(String loggerName, ... Message message, ...)
{
    this.endOfBatch = false;
    this.loggerName = loggerName;
    this.marker = marker;
    this.loggerFqcn = loggerFQCN;
    this.level = level == null?Level.OFF:level;
    this.message = message;                    // <--- issue is seen here
    ...


问题在于分配到message字段中。
messageParameterizedMessagegrepcode),
并且有一个formattedMessage字段,它是一个字符串。

只需跳过this.message = message,变量/监视窗口就会显示message的所有字段
按照预期将其复制到this.message中,但渲染的formattedMessage除外(从null更改为实际渲染的字符串)。

源代码步骤之前的屏幕快照(IntelliJ Ultimate 2017.1):

java - 在IntelliJ中执行源步骤后意外呈现Log4j消息对象-LMLPHP

源代码步骤之后的屏幕截图-注意formattedMessage的值:

java - 在IntelliJ中执行源步骤后意外呈现Log4j消息对象-LMLPHP

查看ParameterizedMessage的代码,唯一可以执行此渲染的功能是formatMessage,称为
通过getFormattedMessage()。因此,我的工作假设是getFormattedMessage()以某种方式被调用。

我的问题:


甚至可能-隐式调用getFormattedMessage()吗?
还是有一些正在执行的代码,但是IntelliJ没有显示?
还是我缺少一些最基本的东西?


当尝试“进入”此语句时,它只是在其上执行。
我试图在getFormattedMessage()ParameterizedMessage的所有其他功能上放置断点,
但是在执行此源代码步骤时,没有任何命中。

最佳答案

您所看到的是toString()的工作。调试器显示基于toString()的值,在这种情况下,toString()调用getFormattedMessage()

因此,分配不是做任何事情,而是调试器调用toString()并通过该工作来做。

10-08 00:20