Java Logger - подсказка Netbeans Неэффективное использование конкатенации строк в регистраторе

Я начинаю с java и пытаюсь что-то записать.

private static final Logger _logger = Logger.getLogger("my"); 

String car = "bmw";
String dog = "dog"; 

_logger.info(car + " text " + dog); // on this line Netbeans

.. в этой строке Netbeans показывает мне желтую лампочку и говорит: Неэффективное использование конкатенации строк в регистраторе

Поэтому я нажимаю «Преобразовать конкатенацию строк в шаблон сообщения», и он меняет код на:

_logger.log(Level.INFO, "[{0}] v{1} enabled", new Object[]{car, dog});

Это вызывает проблемы. Потому что в логе вижу: [{0}] v{1} enabled Как исправить?


person user1571252    schedule 07.09.2012    source источник
comment
Попробуйте _logger.log(Level.INFO, String.format("[{0}] v{1} enabled", new Object[]{car, dog}))   -  person Ryan Amos    schedule 07.09.2012
comment
@Ryan Amos: Вы должны опубликовать это как ответ, и что-то нужно сделать с названием вопроса.   -  person nevets1219    schedule 07.09.2012
comment
Используете ли вы Logger, который поставляется с Java, или стороннюю структуру ведения журнала. Сгенерированный код выглядит так, как будто он должен работать в соответствии с документацией Logger, но я никогда не использовал среду ведения журналов Java.   -  person Michael Krussel    schedule 07.09.2012
comment
Как сказал @MichaelKrussel - какой Formatter используется? Можете ли вы загрузить свою конфигурацию ведения журнала?   -  person Dilum Ranatunga    schedule 07.09.2012
comment
Где вы видите эту проблему?   -  person Roman C    schedule 08.09.2012
comment
См. также stackoverflow.com/questions/9790860/   -  person Philip Durbin    schedule 01.02.2013


Ответы (4)


У вас есть несколько вариантов

1) Используйте String.format() _logger.log(Level.INFO, String.format("[%s] %s enabled", car, dog)).

2) Используйте StringBuilder.append() или String.concat()`.

Ex: _logger.log(Level.INFO, new StrinBuilder(car).append(" text ").append(dog));

По сути, это то, что javac делает при оптимизации.

3) Игнорируйте предупреждение, потому что эффективность здесь не имеет значения. Если бы вы действительно заботились о скорости, вы бы ничего не регистрировали. Ведение журнала занимает много времени, и разница между форматированием строк и добавлением строк очень мала по сравнению со временем, затрачиваемым на запись журнала.

person Ryan Amos    schedule 07.09.2012
comment
@user1571252 user1571252 Попробуйте новую вещь, которую я поставил. Я не часто использую String.format. - person Ryan Amos; 07.09.2012
comment
Причина использования аргументов вместо объединения состоит в том, чтобы избежать создания строки, если уровень журнала выше, чем INFO. Все ваши предложения будут создавать строку каждый раз. - person Michael Krussel; 07.09.2012
comment
Правильное использование для # 1 String.format( "%s %s enabled", car, dog ) - person nevets1219; 07.09.2012
comment
@MichaelKrussel Хотя это правда, я не могу вспомнить ни одного случая, когда я когда-либо писал что-то, где ведение журнала было бы неэффективным (хотя с C# у меня регистратор выдавал ошибку и приводил к сбою приложения) - person Ryan Amos; 07.09.2012
comment
@nevets1219 Спасибо! Я починил это. - person Ryan Amos; 07.09.2012
comment
Проголосовали против, потому что все они выполняют форматирование и объединение строк, прежде чем определить, нужно ли выводить сообщение журнала. - person Dilum Ranatunga; 07.09.2012
comment
-1 редактирование несколько раз и все же практически не используемое решение. - person Roman C; 07.09.2012
comment
@RomanC Что ты имеешь в виду? Все 3 из этих решений являются полезными и практичными. - person Ryan Amos; 07.09.2012
comment
@DilumRanatunga Я вижу, вы хотите сыграть в игру с отрицательным голосованием, в которой вы отрицаете ответ всех остальных. Я бы предпочел не играть в нее. - person Ryan Amos; 07.09.2012
comment
@RyanAmos, я проголосовал против всего, что в основном говорило: не используйте API ведения журнала и игнорируйте предупреждения о производительности. Конечно, API-интерфейсы ведения журналов не идеальны, и иногда IDE могут излишне усердствовать. Но, возможно, есть причина для API. И еще одна причина, по которой вывод неправильный. - person Dilum Ranatunga; 07.09.2012
comment
@RyanAmos Пока вы не отредактировали свой пост несколько раз. Вы не поняли String.format. - person Roman C; 08.09.2012
comment
@RomanC Теперь это правильно? Вот что важно. Если это не так, дайте мне знать, чтобы я мог это исправить. - person Ryan Amos; 08.09.2012

Это просто полезный совет от Netbeans, на самом деле код

_logger.info(car + " text " + dog); // on this line Netbeans
_logger.log(Level.INFO, "{0} text {1}", new Object[]{car, dog});

получить тот же результат. Первый вариант более удобен для кодера, меньше времени на ввод отладочных сообщений, второй — отлично.

person Roman C    schedule 07.09.2012
comment
Весь смысл параметризованного API заключается в объединении только в том случае, если строка действительно нужна. Например, представьте, что ведение журнала настроено на вывод только SEVERE сообщений. Использование второго API позволяет фреймворку пропускать форматирование. Параметризованные сообщения также являются отправной точкой для локализации сообщений журнала. - person Dilum Ranatunga; 07.09.2012
comment
@DilumRanatunga О каком API ты говоришь? - person Roman C; 07.09.2012
comment
log(Level level, String msg, Object[] params). Согласен, было бы неплохо, если бы был info(String msg, Object[] params). Если вы спрашиваете о локализации, то я говорю о log* методах, у которых на конце стоит *rb, в частности logrb(Level level, ..., Object[] params). - person Dilum Ranatunga; 07.09.2012
comment
@DilumRanatunga это не относится к моему решению. - person Roman C; 07.09.2012
comment
@DilumRanatunga Ваши аргументы не относятся к вопросу ОП. - person Roman C; 07.09.2012

Любой подход, при котором депараметризованная строка генерируется до определения того, следует ли записывать сообщение, является неэффективным.

Вероятно, у вас плохо написано java.util.logging.Formatter. Под этим я подразумеваю средство форматирования, которое просто выводит LogRecord.getMessage() вместо включения LogRecord.getParameters()

person Dilum Ranatunga    schedule 07.09.2012
comment
Ничего плохого не написано. - person Roman C; 08.09.2012

Это фактическое форматирование netbeans 7.1.2.

public class Vels4j {

    private static final Logger _logger = Logger.getLogger("my");
    String car = "bmw";
    String dog = "dog";

    Vels4j() {
       // _logger.info(car + " text " + dog);
        _logger.log(Level.INFO, "{0} text {1}", new Object[]{car, dog});
    }

    public static void main(String[] args) {
        Vels4j vels4j = new Vels4j(); 
    }
}

Вы можете отключить подсказки, если не хотите. Также подсказка может быть настроена.

person vels4j    schedule 07.09.2012