Les modèles «statiques» ne devraient-ils pas toujours être statiques?

Je viens de trouver un bug dans un code que je n’ai pas écrit et je suis un peu surpris:

Pattern pattern = Pattern.comstack("\\d{1,2}.\\d{1,2}.\\d{4}"); Matcher matcher = pattern.matcher(s); 

Malgré le fait que ce code échoue mal sur les données d’entrée que nous obtenons (car il essaie de trouver des dates au format 17.01.2011 et récupère des informations telles que 10396/2011, puis s’est écrasé car il ne peut pas parsingr la date, Le sharepoint cette question;) Je me demande:

Il y a tellement d’exemples, partout sur le Web, où le même motif est toujours recompilé à l’aide de Pattern.comstack que je commence à me demander si je vois des choses ou non.

N’est-ce pas (en supposant que la chaîne est statique et donc non construite dynamicment):

 static Pattern pattern = Pattern.comstack("\\d{1,2}.\\d{1,2}.\\d{4}"); 

toujours préférable à une référence de modèle non statique?

  1. Oui, le but de pré-comstackr un Pattern est de ne le faire qu’une fois.
  2. Cela dépend vraiment de la manière dont vous allez l’utiliser, mais en général, les modèles pré-compilés stockés dans static champs static devraient convenir. (Contrairement aux Matcher , qui ne sont pas threadsafe et ne doivent donc pas être stockés dans des champs, statiques ou non.)

Le seul inconvénient de la compilation de modèles dans les initialiseurs statiques est que si le modèle ne comstack pas et que l’initialiseur statique lève une exception, la source de l’erreur peut être assez gênante à rechercher. C’est un problème de maintenabilité mineure, mais cela mérite d’être mentionné.

D’abord, le bug dans le motif est que dot (.) correspond à tout. Si vous voulez faire correspondre un point (.), Vous devez l’échapper avec regex:

Pattern pattern = Pattern.comstack("\\d{1,2}\\.\\d{1,2}\\.\\d{4}");

Deuxièmement, Pattern.comstack() est une méthode lourde. Il est toujours recommandé d’initialiser un modèle statique (je veux dire des modèles qui ne sont ni modifiés ni générés à la volée) une seule fois. L’un des moyens les plus répandus d’atteindre cet objective consiste à placer Pattern.comstack() dans un initialiseur statique.

Vous pouvez utiliser une autre approche. Par exemple, utiliser un motif singleton ou un framework qui crée des objects singleton (comme Spring).

Oui, comstackr le motif à chaque utilisation est une perte de temps et sa définition statique améliorerait les performances. Voir ce fil SO pour une discussion similaire.

Les modèles statiques restraient en mémoire tant que la classe est chargée.

Si vous êtes inquiet au sujet de la mémoire et que vous voulez un Pattern jeter que vous utilisez de temps en temps et qui peut se ramollir lorsque vous avez fini, vous pouvez utiliser un Pattern non statique.

C’est un compromis classique entre le temps et la mémoire. Si vous comstackz un motif une seule fois, ne le collez pas dans un champ statique. Si vous avez mesuré que la compilation de Patterns est lente, pré-comstackz-la et placez-la dans un champ statique.