web-dev-qa-db-ja.com

Java regexパターン-コンパイル時定数またはインスタンスメンバー?

現在、私はいくつか持っています シングルトン 正規表現でマッチングを実行しているオブジェクト、および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 */ }
}

しかし、先日、これは悪いスタイルだと誰かから言われました。Pattern常に クラスレベルで定義され、代わりに次のようになります。

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 */ }
}

この特定のオブジェクトの寿命はそれほど長くはありません。最初のアプローチを使用する主な理由は、オブジェクトがGCされるとPatternsを保持することが意味をなさないためです。

提案/考えはありますか?

13
yamafontes

Java Pattern オブジェクトはスレッドセーフで不変です(マッチャーはスレッドセーフではありません)。

そのため、それらがクラスの各インスタンスで使用される場合(または、再度別のメソッドで使用される場合)、それらをstaticにする理由notはありません。クラス)。

それらをインスタンス変数にすることは、その寿命がどれほど短い(または長い)かに関係なく、クラスのインスタンスを作成するたびに正規表現を再コンパイルすることを意味します。

この構造(PatternがMatcherオブジェクトのファクトリーである)の主な理由の1つは、compile正規表現をその有限オートマトンにコンパイルするのが適度にコストのかかるアクションであることです。ただし、特定のクラスで同じ正規表現が何度も使用されることがよくあります(同じメソッドの複数の呼び出しまたはクラス内の異なるスポットのいずれかを介して)。

一方、Matcherはかなり軽量です。Pattern内のパターンの状態と文字列の文字配列内の場所を指します。


singletonの場合、tooはそれほど重要ではありません。結局のところ、そのインスタンスは1つしかなく、シングルトンを何度も再作成していない(待って、「シングルトンの寿命はそれほど長くない」?)これは、の過程で複数回インスタンス化していることを意味しますか?アプリケーション?)

ただし、一部の静的ソースコードアナライザーは、何かがシングルトンであることを認識せず、クラスの各インスタンスの定数からパターンのインスタンスを作成していると文句を言うでしょう。

これらすべての問題は、それが良くない(シングルトンにとっても悪くない)選択であり、コンパイラーと分析ツールがあなたに告げることについて他の警告を無視し始めるかもしれないということです(詳細については 壊れたウィンドウ )。

関連:

18
user40980