1

考虑以下语句并将日志级别设置为错误。正在使用的日志记录 API 是 log4j。给出上述信息将创建多少个字符串?

if (logger.isDebugEnabled()) {
    logger.debug("Executing SQL query [" + sql + "]");
}

另一个问题是

if (logger.isDebugEnabled()) {
     StringBuilder sBuilder = new StringBuilder("Executing SQL query [");
     sBuilder.append(sql);
     sBuilder.append("]");
     logger.debug(sBuilder.toString());
}

在上述情况下将创建多少个字符串?

我的问题是即使没有为调试启用记录器,编译器也会创建字符串吗?

4

2 回答 2

2

如果源代码中有引号,那么无论代码多么复杂,编译器都会将字符串常量放入池中。编译器不会做很多假设,除非它可以清楚地看到代码不可访问(如if(false))。

你可能想看看 slf4j with logback 它允许你写

log.debug("Executing SQL query [{}]", sql);

请注意,在运行时,它仍然会创建 aStringBuilder并从模式和参数构建结果,但 slf4j 会if为您完成。这将使您的代码保持干净和快速,而无需付出太多努力。

您可能想查看Lombok 项目及其@Log 注释,以使其更加简单和紧凑。

于 2013-10-29T10:46:49.573 回答
2
logger.debug("Executing SQL query [" + sql + "]");

两串

"Executing SQL query [" 

"]"

在编译时创建。

然后,在运行时,

"Executing SQL query [" + sql + "]"

(+) 运算符返回 new StringBuilder(string...).toString()在堆内存JVM中创建一个新的 String实例。

StringBuilder.toString如果启用调试,附加操作将发生。

于 2013-10-29T09:34:21.123 回答