以下部分代码引发了SonarQube的一个主要错误:
“只是有条件地调用方法。”
我该如何解决这个问题?
if(us != null){
logger.info("Log this: {}", us.toString());
}
答案 0 :(得分:15)
对@echo off
setlocal
call :prompt "Fill in the blank:" response
echo You entered "%response%"
call :prompt "This is a prompt of a different length:" response
echo You entered "%response%"
<NUL set /P "=Press any key to exit. " & pause >NUL & echo;
goto :EOF
:prompt <question> <return_var>
setlocal disabledelayedexpansion
set "dots=................................................................................"
for /f "skip=4 tokens=2 delims=:" %%I in ('mode con') do if not defined cols (
set /a cols = %%I - 4
)
call set "dots=%%dots:~-%cols%%%"
rem // credit: https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/AUXP8XbRAJA
for /f %%a in ('copy /Z "%~dpf0" nul') do endlocal & set /P "%~2=%dots%%%a%~1 " & exit /b
的调用是多余的,无论配置的日志级别如何,都将调用us.toString()
方法。您应该仅将toString()
作为参数传递给us
而不使用info
语句。
if
答案 1 :(得分:7)
正如问题的评论所述,另一个有效的答案是:
if(logger.isInfoEnabled() && us != null){
logger.info("Log this: {}", us.toString());
}
答案 2 :(得分:1)
您可以忽略它,但是如果可能的话,处理这种情况可能会很好,它将帮助我们处理和切断不必要的计算。
这里建议的一件事是检查您要使用的日志级别是否已启用。
if(logger.isInfoEnabled() && us != null){
// this inner code will only get executed if the above is true
logger.info("Log this: {}", us.toString());
}
想象一下,如果内部有一个复杂的任务正在运行,那么如果禁用了日志级别,那么无论如何都不打算记录它,那将是浪费时间。记录器将在内部为您检查,但现在在调用.info()
之前执行此操作将为您节省一些时间。
答案 3 :(得分:1)
将需要进一步评估的消息参数传递给Guava com.google.common.base。前提条件检查可能会导致性能下降。这是因为无论是否需要它们,每个参数都必须在实际调用该方法之前进行解析。
类似地,将串联字符串传递到日志记录方法中也可能造成不必要的性能损失,因为无论日志级别是否足够低以显示消息,每次调用该方法时都会执行串联。
相反,您应该构建代码结构,以将静态或预先计算的值传递到Preconditions条件检查和记录调用中。
具体地说,应该使用内置的字符串格式而不是字符串连接,如果消息是方法调用的结果,则应该完全跳过前提条件,而应该有条件地抛出相关的异常。 / p>
不兼容的代码示例
logger.log(Level.DEBUG, "Something went wrong: " + message);
// Noncompliant; string concatenation performed even when log level too high to show DEBUG messages
logger.fine("An exception occurred with message: " + message);
// Noncompliant
LOG.error("Unable to open file " + csvPath, e); // Noncompliant
Preconditions.checkState(a > 0, "Arg must be positive, but got " + a);
// Noncompliant. String concatenation performed even when a > 0
Preconditions.checkState(condition, formatMessage()); // Noncompliant. formatMessage() invoked regardless of condition
Preconditions.checkState(condition, "message: %s", formatMessage());
// Noncompliant
兼容解决方案
logger.log(Level.SEVERE, "Something went wrong: {0} ", message);
// String formatting only applied if needed
logger.fine("An exception occurred with message: {}", message);
// SLF4J, Log4j
logger.log(Level.SEVERE, () -> "Something went wrong: " + message);
// since Java 8, we can use Supplier , which will be evaluated lazily
LOG.error("Unable to open file {0}", csvPath, e);
if (LOG.isDebugEnabled() {
LOG.debug("Unable to open file " + csvPath, e);
// this is compliant, because it will not evaluate if log level is above debug.
}
Preconditions.checkState(arg > 0, "Arg must be positive, but got %d", a); // String formatting only applied if needed
if (!condition) {
throw new IllegalStateException(formatMessage()); /
/ formatMessage() only invoked conditionally
}
if (!condition) {
throw new IllegalStateException("message: " + formatMessage());
}
例外
catch块将被忽略,因为在特殊路径上性能损失并不重要(catch块不应成为标准程序流程的一部分)。吸气剂以及在注解上调用的方法都可以被视为吸气剂,它们将被忽略。该规则说明了使用SLF4J方法isXXXEnabled进行的显式测试级测试,并忽略了此类if语句的主体。