在调试一些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);
}
Log4jLogEvent
(grepcode)的符号是一种简单的方法,它将给定的参数分配给新构造的对象字段:
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
字段中。message
是ParameterizedMessage
(grepcode),并且有一个
formattedMessage
字段,它是一个字符串。只需跳过
this.message = message
,变量/监视窗口就会显示message
的所有字段按照预期将其复制到
this.message
中,但渲染的formattedMessage
除外(从null
更改为实际渲染的字符串)。源代码步骤之前的屏幕快照(IntelliJ Ultimate 2017.1):
源代码步骤之后的屏幕截图-注意
formattedMessage
的值:查看
ParameterizedMessage
的代码,唯一可以执行此渲染的功能是formatMessage
,称为通过
getFormattedMessage()
。因此,我的工作假设是getFormattedMessage()
以某种方式被调用。我的问题:
甚至可能-隐式调用
getFormattedMessage()
吗?还是有一些正在执行的代码,但是IntelliJ没有显示?
还是我缺少一些最基本的东西?
当尝试“进入”此语句时,它只是在其上执行。
我试图在
getFormattedMessage()
和ParameterizedMessage
的所有其他功能上放置断点,但是在执行此源代码步骤时,没有任何命中。
最佳答案
您所看到的是toString()
的工作。调试器显示基于toString()
的值,在这种情况下,toString()
调用getFormattedMessage()
。
因此,分配不是做任何事情,而是调试器调用toString()
并通过该工作来做。