Padrões de regex Java - compilar constantes de tempo ou membros de instância?

12

Atualmente, tenho alguns objetos singleton nos quais estou fazendo correspondência em expressões regulares, e meus Patterns são definidos assim:

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

Mas alguém me disse outro dia que esse é um estilo ruim, e semprePattern deve ser definido no nível da classe e, em vez disso, é algo parecido com isto:

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

A vida útil desse objeto em particular não é tão longa, e minha principal razão para usar a primeira abordagem é porque não faz sentido para mim manter os Patterns quando o objeto recebe GC.

Alguma sugestão / pensamento?

yamafontes
fonte

Respostas:

17

Os objetos Java Pattern são thread-safe e imutáveis ​​(são os correspondentes que não são thread-safe).

Como tal, não há razão para não criá-las staticse elas serão usadas por cada instância da classe (ou novamente em outro método da classe).

Tornando-os variáveis ​​de instância, não importa quão curto (ou longo) seu tempo de vida, significa que você está recompilando a expressão regular cada vez que cria uma instância de uma classe.

Uma das principais razões para essa estrutura (o Pattern é uma fábrica para objetos Matcher) é que compilar a expressão regular em seus autômatos finitos é uma ação moderadamente cara. No entanto, verifica-se que muitas vezes a mesma expressão regular é usada repetidamente em uma determinada classe (através de várias invocações do mesmo método ou de pontos diferentes da classe).

O Matcher, por outro lado, é bastante leve - aponta para o estado do padrão dentro do Padrão e o local na matriz de caracteres da sequência.


Para um singleton , não deve importa muito muito, porque afinal de contas, há apenas uma instância dele que se senta ao redor e você não está recriando o singleton novo e de novo (espera, 'tempo de vida do singleton não é tanto tempo' ? Isso significa que você está instanciando-o várias vezes ao longo do aplicativo?)

No entanto, você descobrirá que alguns analisadores de código-fonte estáticos não reconhecem que algo é um singleton e reclamarão que você está criando instâncias de padrões a partir de constantes para cada instância da classe.

O problema de tudo isso é que não é uma boa opção (também não é ruim para um singleton) e você pode começar a ignorar outros avisos sobre coisas que as ferramentas de análise e compilador lhe dizem (leia mais sobre janelas quebradas ).

Palavras-chave:

Comunidade
fonte
Resposta impressionante - sim, eu quis dizer que ele só é criado / usado apenas uma vez e, uma vez que sai do escopo, é feito para sempre. Obrigado pela leitura de acompanhamento!
Yamafontes