Modèles d'expression régulière Java - compiler des constantes de temps ou des membres d'instance?

13

Actuellement, j'ai quelques objets singleton où je fais la correspondance sur des expressions régulières, et mes Patterns sont définis comme suit:

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

Mais quelqu'un m'a dit l'autre jour que c'était un mauvais style, et que Patterns devrait toujours être défini au niveau de la classe, et ressembler à ceci à la place:

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

La durée de vie de cet objet particulier n'est pas si longue, et ma principale raison d'utiliser la première approche est parce que cela n'a pas de sens pour moi de conserver le Patterns une fois que l'objet est GC'd.

Des suggestions / réflexions?

yamafontes
la source

Réponses:

18

Les objets Java Pattern sont thread-safe et immuables (ce sont les matchers qui ne sont pas thread-safe).

En tant que tel, il n'y a aucune raison de ne pas les créer statics'ils vont être utilisés par chaque instance de la classe (ou encore dans une autre méthode de la classe).

En les transformant en variables d'instance, quelle que soit leur durée de vie (courte ou longue), vous recompilez l'expression régulière à chaque fois que vous créez une instance d'une classe.

L'une des principales raisons de cette structure (Pattern étant une fabrique d'objets Matcher) est que la compilation de l'expression régulière dans ses automates finis est une action modérément coûteuse. Cependant, on constate que souvent la même expression régulière est utilisée encore et encore dans une classe donnée (soit par le biais de plusieurs invocations de la même méthode ou de différents spots dans la classe).

Le Matcher, quant à lui, est plutôt léger - il indique l'état du motif dans le motif et l'emplacement dans le tableau de caractères de la chaîne.


Pour un singleton , cela ne devrait pas trop d' importance, car après tout, il n'y a qu'une seule instance de celui-ci et vous ne recréez pas le singleton encore et encore (attendez, `` la durée de vie du singleton n'est pas si longue '' ? Est -ce que cela signifie que vous êtes instancier plusieurs fois au cours de l'application?)

Cependant, vous constaterez que certains analyseurs de code source statiques ne reconnaissent pas que quelque chose est un singleton et se plaindront que vous créez des instances de modèles à partir de constantes pour chaque instance de la classe.

Le problème avec tout cela est que ce n'est pas un bon choix (ce n'est pas mauvais pour un singleton non plus) et vous pouvez commencer à ignorer d'autres avertissements pour des choses dont le compilateur et les outils d'analyse vous parlent (en savoir plus sur les fenêtres cassées ).

En relation:

Communauté
la source
Réponse impressionnante - oui, je voulais dire qu'elle n'est jamais créée / utilisée qu'une seule fois, et une fois qu'elle est hors de portée, c'est fait pour de bon. Merci pour la lecture de suivi!
yamafontes