Java正規表現パターン-時定数またはインスタンスメンバーをコンパイルしますか?


12

現在、正規表現でマッチングを行っているシングルトンオブジェクトがいくつかあり、私Patternのsは次のように定義されています。

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

この特定のオブジェクトの存続期間はそれほど長くはありません。最初のアプローチを使用する主な理由はPattern、オブジェクトがGCになったらs を保持する意味がないためです。

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

回答:


17

Java パターンオブジェクトはスレッドセーフで不変です(スレッドセーフではないマッチャー)。

そのため、クラスの各インスタンスで(またはクラスの別のメソッドで)使用される場合、それらを作成しない理由はありませんstatic

インスタンス変数を作成すると、その寿命がどれほど短い(または長い)場合でも、クラスのインスタンスを作成するたびに正規表現を再コンパイルすることになります。

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

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


以下のためにシングルトン、それは問題ではないはずですあまりにも多くの、ためには、すべての後に、「長いということではありませんシングルトンの寿命」(待機を、周りに座って、あなたが再び再びとシングルトンを再作成されないことのインスタンスは1つだけです?これは、あなたがどういう意味しているアプリケーションの過程で、それを複数回インスタンス化?)

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

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

関連:


素晴らしい答え-はい、私はそれが一度だけ作成/使用されたことを意味し、一度範囲外になるとそれは永久に行われます。フォローアップを読んでくれてありがとう!
ヤマフォンテス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.