2017-02-22 4 views
3

Я использую SonarLint, что показывает мне проблему в следующей строке.Встроенное форматирование строк и конкатенация строк в качестве параметра регистрации

LOGGER.debug("Comparing objects: " + object1 + " and " + object2); 

Боковое примечание: метод, содержащий эту строку, может часто вызываться.

описания для этого вопроса

«Предпосылки» и аргументы лесозаготовительных не должны требовать оценки (кальмара: S2629)

Передачи аргументов сообщений, которые требуют дальнейшей оценки в Гуава com.google. common.base. Проверка условий может привести к штрафу . Это потому, что независимо от того, нужны они или нет, каждый аргумент должен быть разрешен до вызова метода.

Аналогично, передавая сцепленные строки в метод регистрации может также влечет за собой ненужный удар по производительности, так как конкатенация будет выполняется каждый раз, когда метод вызывается, или не является достаточно низким, чтобы показать сообщение уровень журнала .

Вместо этого вы должны структурировать свой код для передачи статических или предварительно вычисленных значений в состояние Предварительные условия проверки и регистрации вызовов.

В частности, встроенные в строке форматировании следует использовать вместо конкатенации, и если сообщение является результатом вызова метода , то Предпосылки должны быть пропущены altoghether и соответствующее исключение следует условно выброшены вместо.

Noncompliant Пример кода

logger.log(Level.DEBUG, "Something went wrong: " + message); // Noncompliant; string concatenation performed even when log level too high to show DEBUG messages 

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 

Compliant Решение

logger.log(Level.SEVERE, "Something went wrong: %s", message); // String formatting only applied if needed 

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 {}", 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()); } 

Я не 100% уверен, понимают ли я на это право. Так почему же это действительно проблема. Особенно это касается эффективности производительности при использовании конкатенации строк. Потому что я часто читаю, что конкатенация строк быстрее, чем форматирование.

EDIT: Может быть, кто-то может объяснить мне разницу между

LOGGER.debug("Comparing objects: " + object1 + " and " + object2); 

И

LOGGEr.debug("Comparing objects: {} and {}",object1, object2); 

в фоновом режиме. Потому что я думаю, что String будет создана до того, как будет передан методу. Правильно? Так что для меня нет разницы. Но очевидно, что я не прав, потому что SonarLint жалуется на это

ответ

3

Я считаю, что у вас есть свой ответ.

Конкатенация заранее рассчитывается условие. Поэтому, если вы условно называете структуру ведения журнала 10K условно, и все они оценивают значение false, вы будете конкатенировать 10K раз без причины.

Также проверьте this topic. И проверьте комментарии Икаро.

Посмотрите также на StringBuilder.

+0

Ответ Икаро говорит о том, что конкатенация строк намного быстрее. Поэтому мне интересно, почему это проблема. О StringBuilder -> если вы видите комментарий AmirRaminar в ответе Икаро, то утверждает, что «+» преобразуется в вызовы StringBuilder компилятором – Naxos84

+0

следующий комментарий для меня интереснее;) – luso

1

Средство конкатенации строк LOGGER.info («Программа начиналась с« + новая дата());

Построено в формате форматирования средств регистрации
LOGGER.info («Программа началась с {}», новой даты());

очень хорошая статья, чтобы понять разницу http://dba-presents.com/index.php/jvm/java/120-use-the-built-in-formatting-to-construct-this-argument

+0

Спасибо за ссылку. Но не могли бы вы обобщить свои слова.Причина в том случае, если ссылка уходит, по крайней мере, резюме присутствует. – Naxos84

+0

Кстати, сложный класс 'Date' был заменен на [' Instant'] (https://docs.oracle.com/javase/9/docs/api/java/time/Instant.html). См. [Учебник по Oracle] (https://docs.oracle.com/javase/tutorial/datetime/). –

1

Рассмотрим ниже о протоколирования:

LOGGER.debug("Comparing objects: " + object1 + " and " + object2); 

что это 'отладки'?

Это уровень ведения журнала, а не уровень LOGGER. См, есть 2 уровня:

а) один из заявления лесозаготовительной (который отлаживать здесь):

"Comparing objects: " + object1 + " and " + object2 

б) Одним из них является уровень журналирования. Итак, каков уровень объекта LOGGER: Это также должно быть определено в коде или в каком-то xml, иначе он берет уровень от его предка.

Теперь, почему я говорю все это?

Теперь оператор регистрации будет напечатан (или более технический термин отправить его «Appender»), если и только если:

Level of logging statement >= Level of LOGGER defined/obtained from somewhere in the code 

Возможные значения уровня могут быть

DEBUG < INFO < WARN < ERROR 

(Может быть немного больше в зависимости от структуры каротажа)

Теперь вернемся к вопросу:

"Comparing objects: " + object1 + " and " + object2 

всегда приведет к созданию строки, даже если мы обнаружим, что «правило уровня», описанное выше, терпит неудачу.

Однако

LOGGER.debug("Comparing objects: {} and {}",object1, object2); 

приведет лишь к формированию строки, если «правило уровень пояснялось выше» удовлетворяет.

Итак, что более разумно?

Проконсультируйтесь с этим url.

+0

Thx для связи. Не могли бы вы предоставить краткое резюме содержимого ссылок? (На всякий случай, когда ссылка будет тормозить в будущем) – Naxos84

Смежные вопросы