Patrones de expresiones regulares Java: ¿compila constantes de tiempo o miembros de instancia?

13

Actualmente, tengo un par de objetos singleton donde estoy haciendo coincidir expresiones regulares, y mis Patterns se definen así:

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

Pero alguien me dijo el otro día que este es un mal estilo, y que los Patterns siempre deben definirse a nivel de clase , y en su lugar debería verse así:

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 vida útil de este objeto en particular no es tan larga, y mi razón principal para usar el primer enfoque es porque no tiene sentido retener el Patterns una vez que el objeto obtiene GC.

¿Alguna sugerencia / pensamiento?

yamafontes
fuente

Respuestas:

18

Los objetos de Java Pattern son seguros para subprocesos e inmutables (son los emparejadores que no son seguros para subprocesos).

Como tal, no hay razón para no hacerlos staticsi van a ser utilizados por cada instancia de la clase (o de nuevo en otro método en la clase).

Hacerlos variables de instancia, sin importar cuán corto (o largo) sea su tiempo de vida significa que está volviendo a compilar la expresión regular cada vez que crea una instancia de una clase.

Una de las razones clave de esta estructura (Pattern es una fábrica para los objetos Matcher) es que compilar la expresión regular en sus autómatas finitos es una acción moderadamente costosa. Sin embargo, uno encuentra que a menudo la misma expresión regular se usa una y otra vez en una clase dada (ya sea a través de múltiples invocaciones del mismo método o diferentes puntos en la clase).

El Matcher, por otro lado, es bastante ligero: señala el estado del patrón dentro del Patrón y la ubicación dentro de la matriz de caracteres para la cadena.


Para un singleton , no debería importar demasiado , porque después de todo, solo hay una instancia de él que se sienta y no está recreando el singleton una y otra vez (espere, 'la vida útil del singleton no es tan larga' ¿Esto significa que lo está instanciando varias veces en el transcurso de la aplicación?)

Sin embargo, encontrará que algunos analizadores de código fuente estático no reconocen que algo es un singleton y se quejarán de que está creando instancias de patrones a partir de constantes para cada instancia de la clase.

El problema con todo esto es que no es una buena opción (tampoco está mal para un singleton) y puede comenzar a ignorar otras advertencias sobre cosas que el compilador y las herramientas de análisis le informan (lea más sobre ventanas rotas ).

Relacionado:

Comunidad
fuente
Respuesta impresionante: sí, quise decir que solo se creó / usó una vez, y una vez que se sale del alcance, se hace para siempre. Gracias por la lectura de seguimiento!
Yamafontes