2012-07-05 21 views
10

Stavo guardando un altro question sulle variabili finali e ho notato che è possibile dichiarare le variabili finali senza inizializzarle (una variabile blank final). C'è una ragione per cui è desiderabile farlo e quando è vantaggioso?Quando è opportuno utilizzare variabili finali vuote?

+1

praticamente mai. le finali in bianco non fanno nulla. sono variabili che non potranno mai avere alcun valore significativo. qualsiasi compilatore java degno di questo nome ti darà un avviso e/o un errore. –

+1

Questo può essere utile quando si desidera inizializzarlo nel costruttore (basato su alcuni parametri del costruttore). – sshannin

+0

La finale è definitiva .. se si tenta di fare final int a = 2; a = 3; genera un errore –

risposta

25

Questo è utile per creare oggetti immutabili:

public class Bla { 
    private final Color color; 

    public Bla(Color c) {this.color = c}; 

} 

Bla è immutabile (una volta creato, non può cambiare perché il colore è definitiva). Ma puoi ancora creare vari Blas costruendoli con vari colori.

Vedere anche this question ad esempio.

EDIT

Forse la pena di aggiungere che un "vuoto finale" ha un significato molto specifico in Java, che sembra aver creato una certa confusione nei commenti - cf il Java Language Specification 4.12.4:

A blank finale è una variabile finale la cui dichiarazione manca di un inizializzatore.

È quindi necessario assegnare quella variabile finale vuota in un costruttore.

+2

Stavo pensando che avevo ragione a dire non puoi farlo :) Non lo sapevo. +1 –

+0

Conciso e chiaro. Grazie! –

2

È possibile eseguire questa operazione quando non si conosce quale sarà il valore precedente alla strumentazione di un oggetto, ma è necessario assegnare un valore nel suo costruttore.

Questo è il modo in cui si effettua immutable objects ed è utilizzato nel modello di builder.

class Builder{ 
    final BuilderContext context; 

    private Builder(BuilderContext context){ 
     this.context=context; 
    }  

    public static Builder New(){ 
     return new Builder(new BuilderContext()); 
    } 
+1

Il compilatore _will_ si lamenta di 'new' come nome di un metodo. –

+0

giusto mi dispiace, passalo a Nuovo, l'ho digitato rapidamente –

+0

Non dovrebbe essere dichiarato statico il metodo New()? @JohnKane – piepi

0

notato che è possibile dichiarare le variabili final senza inizializzare loro

Dovete inizializzare in un secondo momento (ad esempio nel costruttore) in modo da non ci vorrà rimanere vuoto.

4

La proprietà finale della classe deve avere un valore assegnato prima che venga creato l'oggetto. Quindi l'ultimo punto in cui è possibile assegnare loro un valore è il costruttore.

Viene utilizzato spesso per immutable objects.

public class Foo { 

    private final Bar bar; 

    public Foo(Bar bar) { 
    this.bar = bar; 
    } 

    public Bar getBar() { 
    return new Bar(bar); 
} 
} 

What wiki says about it

Defensive copying.

+0

Sì. Questo è ciò a cui si riferisce un "vuoto finale", secondo la citazione di Wikipedia. –

+0

@LouisWasserman, non mi ero reso conto che il wiki lo descrivesse. Ho aggiunto un riferimento a Wiki ma, il tuo "vuoto finale" mostra che Wiki non è il posto migliore per acquisire conoscenze. ;-). –

+0

Aspetta, cosa? La risposta accettata alla domanda secondo cui il PO collegato includeva un link di Wikipedia, che conteneva una citazione che concorda con la tua risposta. –

0

Da Wikipedia

Il vuoto finale, che è stato introdotto in Java 1.1, è una variabile finale la cui dichiarazione manca un inizializzatore. Una finale vuota può essere assegnata una sola volta e deve essere annullata quando si verifica un incarico. Per fare ciò, un compilatore Java esegue un'analisi del flusso per garantire che, per ogni assegnazione a una variabile finale vuota, la variabile sia definitivamente non assegnata prima dell'assegnazione; in caso contrario si verifica un errore in fase di compilazione.

In generale, un compilatore Java assicurerà che il vuoto finale non venga utilizzato fino a quando non viene assegnato un valore e che una volta assegnato un valore, la variabile finale non può essere riassegnata a un altro valore.

1

Le variabili finali vuote devono essere assegnate "da qualche parte" nel costruttore. Un esempio piuttosto costruito:

public class Test { 
    final int sign; 
    public Test(String upDown) { 
     if (upDown.equals("up")) { 
      sign = +1; 
     } else { 
      sign = -1; 
     } 
    } 
} 
1

Un caso potrebbe essere quando si dispone di un campo che si desidera dichiarare finale, ma la cui assegnazione può generare un'eccezione e si vuole essere in grado di intervenire se ciò accade:

class A { 
    final URLConnection conn; 
    A(String url) { 
    try { 
     this.conn = new URL(url).openConnection(); 
    } catch (IOException | MalformedURLException e) { 
     // Maybe this isn't fatal, so just handle the Exception 
     // here and move on happily 
    } 
    } 
} 
1

Utilizzare una variabile finale vuota all'interno di un metodo per mostrare che tutti i percorsi di codice che utilizzano la variabile assegnano tale variabile esattamente una volta (o generano un'eccezione). I compilatori Java garantiranno che una variabile finale vuota viene assegnata prima di essere utilizzata.

codice di esempio all'interno di un metodo:

final Foo foo; 
    if (condition1()) { 
    foo = makeFoo(1); 
    } else if (condition2()) { 
    throw new BarException(); 
    } else { 
    foo = makeFoo(-1); 
    } 
    ... 
    blahBlahBlah(foo); 

Utilizzo delle variabili finali vuote dice al prossimo lettore del codice che le garanzie del compilatore che qualcuno assegnato foo prima di chiamare blahblahblah (foo).

La domanda riguarda "vuoto finale variabili". La discussione sui "campi vuoti finali campi" è una discussione diversa e interessante a sé stante.

Problemi correlati