如何使声纳快乐?

问题描述 投票:1回答:2
log.info(String.format("Execution of method %s finished in %d ms", pointcut.getSignature().getName(), ms))

Sonarlint显示以下错误:

“”先决条件“和日志记录参数不需要评估

兼容解决方案:

logger.log(Level.SEVERE,“出了点问题:{0}”,消息);

让我们尝试一下:

log.info("Execution of method {0} finished in {1} ms", pointcut.getSignature().getName(), ms);

Printf样式的格式字符串应正确使用

兼容解决方案:

String.format(“先是%s,然后是%s”,“ foo”,“ bar”);

我觉得sonarlint只是在嘲笑我。

这是我的判断力,但我并不真正了解发生的情况或为什么他首先抱怨:

String logMessage = String.format("Execution of method %s finished in %d ms", pointcut.getSignature().getName(), ms);
log.info(logMessage);

有什么想法吗?

java sonarlint
2个回答
1
投票

我不是很了解发生的事情,或者他为什么首先抱怨:

第一个示例中提出投诉的原因是,您[[无条件正在做大量工作来构造日志消息。如果日志级别高于INFO,则将浪费工作。


第二个示例比第一个示例更好,因为仅当日志级别为INFO或更低时才从模板创建日志消息字符串。仍会无条件评估pointcut.getSignature().getName()表达式,但是根据您使用的特定日志记录API,这可能是不可避免的。

(((如果进行评估很昂贵,那么您仍然会遇到性能问题。您可以考虑使用if (log.isInfoLevel()) { ... }防护,或者使表达式评估延迟的东西;例如Supplier<String>。但是最好的解决方案是避免记录该昂贵的表达式。)


第二个示例中的Sonar投诉似乎与您在消息/格式字符串中使用的特定语法有关。 @ C.Lechner的答案对此进行了解释:

    在具有{}的第一个版本中,{}的类型在运行时求值。
  • 在第二个具有%s的%d中,您在编译时定义了类型。
  • [如果可能,应使用一种类型,以避免滥用占位符变量,并允许Java编译器进行一些其他检查。
  • 我不完全相信Java编译器会进行检查。 (JLS肯定不是必需的。)但是,编译器或(智能)静态代码分析器可以检查的确是合理的。

    无论哪种方式,都会在运行时再次检查格式字符串。


    最后,这个版本:

    String logMessage = String.format("Execution of method %s finished in %d ms", pointcut.getSignature().getName(), ms); log.info(logMessage);

    与第一个版本存在相同的性能问题,但我怀疑Sonar不够聪明,无法弄清楚。

    0
    投票
      在第一个带有{}的版本中,{}的
    • type在运行时求值。
    • 在第二个带%s的%d中,您在
    • 编译时
    • 定义了type
    [如果可能,应使用一种类型,以避免滥用占位符变量,并允许Java编译器进行一些附加检查。
    © www.soinside.com 2019 - 2024. All rights reserved.