Modelli regex Java: compila costanti di tempo o membri di istanze?

5

Al momento, ho un paio di oggetti singleton in cui eseguo la corrispondenza in espressioni regolari e il mio Pattern s è definito in questo modo:

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

Ma l'altro giorno mi è stato detto che questo è uno stile sbagliato e Pattern s dovrebbe sempre essere definito a livello di classe, e invece assomiglia a questo:

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 durata di questo particolare oggetto non è così lunga, e il motivo principale per cui utilizzo il primo approccio è perché non ha senso per me conservare il Pattern s una volta che l'oggetto ottiene GC'd .

Qualche suggerimento / pensiero?

    
posta yamafontes 02.11.2013 - 20:44
fonte

1 risposta

9

Gli oggetti Java Pattern sono thread safe e immutabili ( è il matcher che non sono thread safe).

Pertanto, non c'è alcun motivo non per renderli static se devono essere usati da ogni istanza della classe (o ancora in un altro metodo della classe).

Rendendoli variabili d'istanza, non importa quanto breve (o lunga) sia la loro vita, significa che stai ricompilando l'espressione regolare ogni volta che crei un'istanza di una classe.

Una delle ragioni principali per questa struttura (Pattern è una fabbrica per gli oggetti Matcher) è che la compilazione dell'espressione regolare nei suoi automi finiti è un'azione moderatamente costosa. Tuttavia, si scopre che spesso la stessa espressione regolare viene usata ancora e ancora in una data classe (o attraverso invocazioni multiple dello stesso metodo o punti diversi nella classe).

Il Matcher, d'altra parte, è piuttosto leggero: punta allo stato del pattern all'interno del Pattern e alla posizione all'interno dell'array di caratteri per la stringa.

Per un singleton , non dovrebbe importare molto too , perché dopo tutto c'è solo una sua istanza che gira intorno e non stai ricreando il singleton ancora e ancora (aspetta, "la vita del singleton non è così lunga"? Questo significa che lo lo istanziate più volte nel corso dell'applicazione?)

Tuttavia, scoprirai che alcuni analizzatori di codice sorgente statici non riconoscono che qualcosa è un singleton e si lamenteranno che stai creando istanze di pattern da costanti per ogni istanza della classe.

Il problema di tutto questo è che è una scelta non buona (non è male nemmeno per un singleton) e si può iniziare a ignorare altri avvisi per cose che il compilatore e gli strumenti di analisi ti dicono (leggi di più su broken windows ).

Related:

risposta data 02.11.2013 - 21:34
fonte

Leggi altre domande sui tag