Java-Regex-Muster - Zeitkonstanten oder Instanzmitglieder kompilieren?

12

Derzeit habe ich einige Singleton- Objekte, bei denen ich reguläre Ausdrücke abgleichen kann, und meine Patterns sind wie folgt definiert:

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

Aber mir wurde neulich von jemandem gesagt, dass dies ein schlechter Stil ist und dass Patterns immer auf Klassenebene definiert werden sollte und stattdessen ungefähr so ​​aussehen sollte:

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

Die Lebensdauer dieses bestimmten Objekts ist nicht so lang, und mein Hauptgrund für die Verwendung des ersten Ansatzes ist, dass es für mich keinen Sinn macht, am Patterns festzuhalten, sobald das Objekt GC-fähig ist.

Anregungen / Gedanken?

yamafontes
quelle

Antworten:

17

Java Pattern- Objekte sind threadsicher und unveränderlich (es sind die Matcher, die nicht threadsicher sind).

Daher gibt es keinen Grund, sie nicht zu staticerstellen, wenn sie von jeder Instanz der Klasse (oder erneut in einer anderen Methode in der Klasse) verwendet werden sollen.

Wenn Sie sie zu Instanzvariablen machen, egal wie kurz (oder lang) ihre Lebensdauer ist, kompilieren Sie den regulären Ausdruck jedes Mal neu, wenn Sie eine Instanz einer Klasse erstellen.

Einer der Hauptgründe für diese Struktur (Pattern ist eine Factory für Matcher-Objekte) ist, dass das Kompilieren des regulären Ausdrucks in seine endlichen Automaten eine mäßig teure Aktion ist. Man stellt jedoch fest, dass in einer bestimmten Klasse häufig immer wieder derselbe reguläre Ausdruck verwendet wird (entweder durch mehrere Aufrufe derselben Methode oder durch verschiedene Stellen in der Klasse).

Der Matcher hingegen ist eher leicht - er zeigt auf den Status des Musters innerhalb des Musters und die Position innerhalb des Zeichenarrays für die Zeichenfolge.


Für einen Singleton sollte es nicht allzu wichtig sein , denn schließlich gibt es nur eine Instanz davon, und Sie erstellen den Singleton nicht immer wieder neu (warten Sie, die Lebensdauer des Singletons ist nicht so lang). ? Bedeutet dies, dass Sie es im Verlauf der Anwendung mehrmals instanziieren?)

Sie werden jedoch feststellen, dass einige statische Quellcode-Analysatoren nicht erkennen, dass es sich um einen Singleton handelt, und sich beschweren, dass Sie Instanzen von Mustern aus Konstanten für jede Instanz der Klasse erstellen.

Das Problem bei all dem ist, dass es keine gute Wahl ist (es ist auch nicht schlecht für einen Singleton) und Sie möglicherweise andere Warnungen für Dinge ignorieren, über die Ihnen der Compiler und die Analysetools berichten (lesen Sie mehr über kaputte Fenster ).

Verbunden:

Gemeinschaft
quelle
Tolle Antwort - ja, ich meinte, es wird immer nur einmal erstellt / verwendet, und sobald es den Rahmen verlässt, ist es endgültig erledigt. Vielen Dank für die Nachlesung!
Yamafontes