考虑以下语句并将日志级别设置为ERROR。正在使用的日志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());
}
在上述情况下会创建多少个字符串?
我的问题是,即使没有为调试启用记录器,编译器也会创建字符串吗?
答案 0 :(得分:2)
logger.debug("Executing SQL query [" + sql + "]");
两个字符串
"Executing SQL query ["
"]"
在编译时创建。
然后,在运行时,
"Executing SQL query [" + sql + "]"
(+)operator JVM
返回新的StringBuilder(string ...)。toString(),它在堆内存中创建 new String 实例。
如果调试启用,则StringBuilder.toString
将发生追加操作。
答案 1 :(得分:2)
如果源代码中有引号,那么无论代码有多复杂,编译器都会将字符串保持为常量。编译器没有做出很多假设,除非它能清楚地看到代码无法访问(如if(false)
)。
您可能希望看一下带有logback的slf4j,它允许您编写
log.debug("Executing SQL query [{}]", sql);
请注意,在运行时,它仍会创建StringBuilder
并根据模式和参数构建结果,但slf4j将为您执行if
。这将使您的代码保持清洁和快速,而无需花费太多精力。
您可能希望查看project Lombok及其@Log annotation,以使其更轻松,更紧凑。