2010-02-26 15 views

risposta

33

Sì, certo: static final variabili possono essere inizializzato in un blocco statico ma .... in questo esempio sono presenti GOTO impliciti (try/catch è essenzialmente un "GOTO catch se succede qualcosa di brutto").

Se viene generata un'eccezione, le variabili final non verranno inizializzate.

Si noti che l'uso di costrutti statici va contro il dogma orientato agli oggetti. Potrebbe complicare il tuo test e rendere più difficile il debugging.

+1

È possibile eseguire un'eccezione dal 'blocco di inizializzazione statico'. Cosa posso fare quando un codice nel 'blocco di inizializzazione statico 'genera qualche eccezione che non voglio gestire. –

+0

è possibile inizializzare le variabili all'esterno del blocco catch try, ad es. facendo il codice di lancio delle eccezioni in try catch e inizializzando finalmente ... – awk

+3

@awk: avrebbe bisogno di usare i locali per fare il compito se il codice di lancio delle eccezioni è la chiamata al metodo getString (...). –

17

È possibile eseguire questa operazione ma è necessario uscire dal blocco statico generando un'eccezione: è possibile ripetere l'analisi dell'eccezione rilevata o di una nuova. Generalmente questa eccezione deve essere RuntimeException. Davvero non dovresti prendere un generico Exception ma eccezioni più specifiche che potrebbero essere lanciate dal tuo blocco try. Infine, se un inizializzatore statico genera un'eccezione, renderà la classe inutilizzabile durante quella specifica esecuzione poiché la JVM tenterà di inizializzare la classe solo una volta. I tentativi successivi di utilizzare questa classe genereranno un'altra eccezione, ad esempio NoClassDefFoundError.

Quindi, al lavoro, il vostro initializer dovrebbe leggere qualcosa di simile:

static { 
    try { 
     ... 
    } catch (Exception e) { 
     e.PrintStackTrace(); 
     throw new InitializationFailedException("Could not init class.", e); 
    } 
} 

Supponendo che InitializationFailedException è una consuetudine RuntimeException, ma è possibile utilizzare uno esistente.

+0

Non sei sicuro del motivo per cui ci fosse un voto negativo, per favore spiega. –

0

Puoi inserire la dichiarazione nel blocco finally?

try { 
    //load file 
} catch(IOException e) { 
    // horay 
} finally { 
    HOST=config.get...... 
} 
+1

Questo non è possibile. – pvorb

8
public class MyClass 
{ 
    private static final SomeClass myVar; 

    static 
    { 
     Object obj = null; // You could use SomeClass, but I like Object so you can reuse it 
     try 
     { 
      obj = new SomeClass(...);  
     } 
     catch(WhateverException err) 
     { 
      // Possibly nested try-catches here if the first exception is recoverable... 
      // Print an error, log the error, do something with the error 
      throw new ExceptionInInitializerError(err); 
     } 
     finally 
     { 
      myVar = (SomeClass) obj; 
     } 
    } 
} 

Supponendo che nessun dove a monte è in grado di catturare sia un ExceptionInInitializationError o un generale Eccezione quindi il programma non dovrebbero mai cercare di utilizzare myVar. Se tuttavia vengono catturati e il programma non termina, è necessario codificare per controllare e gestire myVar essere nullo (o essere felici con NullPointerExceptions che esce dappertutto).

Non sono sicuro che ci sia un buon modo per gestirlo.

+1

>>> _questo è necessario codice per guardare e gestire myVar essere null_ Qui l'inizializzatore statico genera un'eccezione che impedisce il caricamento della classe (e quindi le variabili non possono essere referenziate non inizializzate) quindi non c'è bisogno di preoccuparsi per NPE (eccezione puntatore nullo) – sactiw

Problemi correlati