【问题标题】:How many string object will be created in constant pool常量池中将创建多少个字符串对象
【发布时间】:2013-10-29 09:32:42
【问题描述】:

考虑以下语句并将日志级别设置为错误。正在使用的日志记录 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());
}

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

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

【问题讨论】:

    标签: java string logging log4j


    【解决方案1】:
    logger.debug("Executing SQL query [" + sql + "]");
    

    两个字符串

    "Executing SQL query [" 
    
    "]"
    

    在编译时创建。

    然后,在运行时,

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

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

    如果启用调试,附加操作将使用StringBuilder.toString 进行。

    【讨论】:

    • 这些也会在运行时加载吗?
    • @Jabir 当然,这是一个简单的 java 行,不管它是记录器还是什么。至少我是这么认为的。
    • @Suresh 我稍微修改了问题,你现在可以检查一下吗
    • @Jabir 同样的事情,创建了两个字符串。一个在运行时解决。
    • @Jabir 请喜欢阅读,stackoverflow.com/questions/7586266/…
    【解决方案2】:

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

    你可能想看看带有 logback 的 slf4j,它允许你写

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

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

    您可能想查看project Lombok 和他们的@Log annotation 以使其更加简单和紧凑。

    【讨论】:

      猜你喜欢
      • 2021-07-04
      • 1970-01-01
      • 2023-03-22
      • 2014-09-14
      • 2019-12-29
      • 1970-01-01
      • 2012-06-26
      • 2012-05-19
      • 1970-01-01
      相关资源
      最近更新 更多