Шаблоны регулярных выражений Java - скомпилируйте постоянные времени или члены экземпляра?

13

В настоящее время у меня есть пара одноэлементных объектов, в которых я выполняю сопоставление с регулярными выражениями, и мои Patterns определяются следующим образом:

class Foobar {
  private final Pattern firstPattern =
    Pattern.compile("some regex");
  private final Pattern secondPattern =
    Pattern.compile("some other regex");
  // more Patterns, etc.
  private Foobar() {}
  public static Foobar create() { /* singleton stuff */ }
}

Но на днях кто-то сказал мне, что это плохой стиль, и Patterns всегда должны быть определены на уровне класса, а вместо этого должны выглядеть примерно так:

class Foobar {
  private static final Pattern FIRST_PATTERN =
    Pattern.compile("some regex");
  private static final Pattern SECOND_PATTERN =
    Pattern.compile("some other regex");
  // more Patterns, etc.
  private Foobar() {}
  public static Foobar create() { /* singleton stuff */ }
}

Время жизни этого конкретного объекта не так долго, и моя главная причина использования первого подхода в том, что мне не имеет смысла держаться за Patterns после того, как объект получит GC'd.

Есть предложения / мысли?

yamafontes
источник

Ответы:

18

Объекты Java Pattern являются поточно-ориентированными и неизменяемыми (сопоставители не являются поточно-ориентированными).

Таким образом, нет причин не делать их, staticесли они будут использоваться каждым экземпляром класса (или снова в другом методе класса).

Назначение им переменных экземпляра, независимо от того, насколько коротким (или длинным) будет их время жизни, означает, что вы перекомпилируете регулярное выражение каждый раз, когда создаете экземпляр класса.

Одна из ключевых причин этой структуры (шаблон, являющийся фабрикой для объектов Matcher) заключается в том, что компиляция регулярного выражения в его конечные автоматы является умеренно дорогостоящим действием. Тем не менее, можно обнаружить, что часто одно и то же регулярное выражение используется снова и снова в данном классе (либо через несколько вызовов одного и того же метода, либо через разные места в классе).

Matcher, с другой стороны, довольно легкий - он указывает на состояние шаблона в шаблоне и местоположение в массиве символов для строки.


Для одноэлементных , он должен не имеет значения слишком много, потому что в конце концов, есть только один экземпляр этого , который сидит вокруг , и вы не воссоздавать одноплодной снова и снова (ожидание, «срок службы синглтона не так долго» ? Значит ли это, что вы выполняете его несколько раз в течение приложения?)

Однако вы обнаружите, что некоторые статические анализаторы исходного кода не распознают что-то одноэлементное и будут жаловаться, что вы создаете экземпляры шаблонов из констант для каждого экземпляра класса.

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

Связанные с:

Сообщество
источник
Потрясающий ответ - да, я имел в виду, что он когда-либо создавался / использовался только один раз, и как только он выходит из области видимости, это делается навсегда. Спасибо за продолжение чтения!
Yamafontes