2012-02-21 20 views
38

Qual è la differenza tra l'inizializzazione all'interno di un blocco di static:Java: quando è utile un blocco di inizializzazione statico?

public class staticTest { 

    static String s; 
    static int n; 
    static double d; 

    static { 
     s = "I'm static"; 
     n = 500; 
     d = 4000.0001; 
    } 
    ... 

E inizializzazione statico individuale:

public class staticTest { 

    static String s = "I'm static"; 
    static int n = 500; 
    static double d = 4000.0001; 

    .... 
+1

Si stanno utilizzando solo assegnazioni nel blocco di inizializzazione statico, quindi ovviamente è possibile farlo utilizzando l'assegnazione di variabili statiche. Hai provato a vedere cosa succede se hai bisogno di eseguire istruzioni di non assegnazione? –

+0

È un buon posto per caricare le classi o caricare la libreria nativa. – qrtt1

+0

Si noti che le variabili statiche dovrebbero essere evitate e quindi i blocchi di inizializzazione statici non sono generalmente una grande idea. Se ti accorgi di usarli molto, aspettati qualche problema lungo la linea. –

risposta

48

A blocchi di inizializzazione statica permette l'inizializzazione più complessi, per esempio usando i condizionali:

static double a; 
static { 
    if (SomeCondition) { 
     a = 0; 
    } else { 
     a = 1; 
    } 
} 

o quando è necessaria più di una semplice costruzione: quando si utilizza un costruttore per creare l'istanza, la gestione delle eccezioni o di lavoro diverso da creare i campi statici sono necessari

Un blocco di inizializzazione statico gestisce anche dopo gli inizializzatori statici in linea, in modo che il seguente è valido:

static double a; 
static double b = 1; 

static { 
    a = b * 4; // Evaluates to 4 
} 
+1

Fare "b = a * 4;" in linea sarebbe solo un problema se b fosse dichiarato prima di a, il che non è il caso nel tuo esempio. –

+1

@GeorgeHawkins Stavo solo cercando di illustrare che un inizializzatore statico funziona dopo inizializzatori in linea, non che un equivalente non possa essere fatto in linea. Tuttavia, prendo il vostro punto e ho aggiornato l'esempio per (si spera) essere più chiaro. –

+0

Solo per divertimento potrei sottolineare che il tuo primo esempio potrebbe facilmente essere "statico double a = someCondition? 0: 1;" Non che i tuoi esempi non siano grandiosi, sto solo dicendo ... :) –

4

Nel tuo esempio, non v'è alcuna differenza; ma spesso il valore iniziale è più complesso di quanto è comodamente espresso in una singola espressione (ad esempio, è un List<String> il cui contenuto è meglio espresso da uno for -loop, oppure è un Method che potrebbe non esistere, quindi sono necessari i gestori di eccezioni), e/o i campi statici devono essere impostati in un ordine specifico.

4

A volte si vuole fare qualcosa di più che semplicemente assegnare valori a variabili statiche. Poiché non è possibile inserire istruzioni arbitrarie nel corpo della classe, è possibile utilizzare un blocco di inizializzazione statico.

3

Tecnicamente, si potrebbe ottenere via senza di essa. Alcuni preferiscono il codice di inizializzazione multilinea per passare a un metodo statico. Sono abbastanza contento di usare un inizializzatore statico per un'inizializzazione a più fasi relativamente semplice.

Naturalmente, quasi sempre eseguo statia final e punto a un oggetto non modificabile.

12

Un utilizzo tipico:

private final static Set<String> SET = new HashSet<String>(); 

static { 
    SET.add("value1"); 
    SET.add("value2"); 
    SET.add("value3"); 
} 

Come fareste senza inizializzatore statico?

+2

Risposta: [Guava] (http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/ collect/ImmutableMap.Builder.html) +1 –

+0

@PaulBellora: P – gawi

+0

Un'altra risposta senza librerie aggiuntive: creare un metodo statico che incapsula l'inizializzazione di 'SET' e utilizzare l'inizializzatore variabile (' statico finale privato Set SET = createValueSet() '). Che cosa succede se hai 5 set e 2 mappe vuoi semplicemente scaricarli tutti in un unico blocco 'static'? – TWiStErRob

0

Il blocco di codice statico consente di inizializzare i campi con più di istuzioni, inizializzare i campi in un ordine diverso delle dichiarazioni e potrebbe anche essere utilizzato per l'inizializzazione condizionale.

Più in particolare,

static final String ab = a+b; 
static final String a = "Hello,"; 
static final String b = ", world"; 

non funzionerà perché a e b sono dichiarati dopo ab.

Tuttavia, potrei usare un init statico. blocco per superare questo.

static final String ab; 
static final String a; 
static final String b; 

static { 
    b = ", world"; 
    a = "Hello"; 
    ab = a + b; 
} 

static final String ab; 
static final String a; 
static final String b; 

static { 
    b = (...) ? ", world" : ", universe"; 
    a = "Hello"; 
    ab = a + b; 
} 
+3

Mentre quello che dici è vero, non dimostra la necessità del blocco di inizializzazione statico. Puoi semplicemente spostare la dichiarazione 'ab' sotto la dichiarazione di' b'. – gawi

8

La gestione delle eccezioni durante l'inizializzazione è un'altra ragione. Ad esempio:

static URL url; 
static { 
    try { 
     url = new URL("https://blahblah.com"); 
    } 
    catch (MalformedURLException mue) { 
     //log exception or handle otherwise 
    } 
} 

Questo è utile per i costruttori che fastidiosamente gettano eccezioni controllate, come sopra, o logiche inizializzazione altro più complicato, potrebbe essere eccezione inclini.

4

static blocco può essere utilizzato per inizializzare singleton esempio, per prevenire utilizzando sincronizzato metodogetInstance().

1

La parola chiave statica (che si tratti di una variabile o di un blocco) appartiene alla classe. Quindi, quando viene chiamata la classe, vengono eseguite queste variabili o blocchi. Quindi la maggior parte dell'inizializzazione verrà effettuata con l'aiuto della parola chiave static. Poiché appartiene alla classe stessa, la classe può accedervi direttamente, senza creare un'istanza della classe.

Facciamo un esempio, c'è una classe di scarpe in cui ci sono diverse variabili come il colore, le dimensioni, marca, ecc ... E qui se la scarpa produzione Società ha solo una marca di quanto dovremmo inizializzarlo come variabile statica . Quindi, quando viene chiamata la classe di scarpe e vengono prodotti diversi tipi di scarpe (creando un'istanza della classe) a quel colore e dimensione occuperanno memoria ogni volta che una nuova scarpa è creata ma qui il marchio è una proprietà comune per tutte le scarpe, in modo che sia occupare memoria per una volta, indipendentemente dal numero di scarpe prodotte.

Esempio:

class Shoe { 
    int size; 
    String colour; 
    static String brand = "Nike"; 

    public Shoe(int size, String colour) { 
     super(); 
     this.size = size; 
     this.colour = colour; 
    } 

    void displayShoe() { 
     System.out.printf("%-2d %-8s %s %n",size,colour, brand); 
    } 

    public static void main(String args[]) { 
     Shoe s1 = new Shoe(7, "Blue"); 
     Shoe s2 = new Shoe(8, "White"); 

     System.out.println("================="); 
     s1.displayShoe(); 
     s2.displayShoe(); 
     System.out.println("================="); 
    } 
} 
0

Un blocco di inizializzazione statico è utile se uno, si desidera inizializzare tipi statici di classe specificato, prima della classe di primo utilizzo. Uso successivo, non invocherà blocchi di inizializzazione statici. È l'esatto opposto degli inizializzatori di istanza, che inizializzano i membri dell'istanza,

Problemi correlati