2010-12-14 12 views
18

Sto rielaborando un codice ereditato, ma sono stato sconcertato dalla decisione di progettazione e non riesco a capire i termini corretti per google. Il mio predecessore userebbe blocchi come questo:In Java, perché avere un blocco di codice senza parole chiave, solo parentesi graffe

public class ChildClass extends ParentClass { 
    { 
     inheritedVar = "someVal"; 
    } 

    public ChildClass(){ /* constructor exists */ } 
    // rest of code 
} 

Qual è il punto di dichiarare un blocco di codice senza parola chiave? Non si comporta come un blocco statico, non credo. È un'alternativa all'impostazione nel costruttore? Questo avrebbe qualche effetto se venisse usata una fabbrica (che in questo caso non lo è)? Ho trovato un thread correlato qui su this happening in C ma il ragionamento (dichiarazione delle variabili &) non sembrava rilevante per Java.

Qualsiasi pensiero o idea sul "perché" di questo sarebbe apprezzato. È abbastanza facile da ridimensionare questo, sono solo curioso di questo punto.

risposta

29

È un blocco di inizializzazione. (In relazione al blocco di inizializzazione statico) Vedere Inizializzazione grado Membri in questa pagina:

http://download.oracle.com/javase/tutorial/java/javaOO/initial.html

Si tratta di un'alternativa ad un costruttore. Potresti usarlo quando fornisci più costruttori sovraccaricati come modo per condividere il codice.

Personalmente, però, trovo molto più chiaro di avere il costruttore chiamare un metodo di inizializzazione chiamato piuttosto che contare sul blocco di codice anonimo. Anche se, il compilatore fa copiare il blocco di inizializzazione per tutti i costruttori che stanno dietro le quinte e si potrebbe sostenere che v'è un aumento di prestazioni simile a inline'ing una dichiarazione di metodo.

+1

+1 per indicare l'uso corretto di questo blocco. – birryree

+1

+1: concordo sui metodi di inizializzazione indicati. Tuttavia, dato che c'è un solo costruttore, l'intero punto di questo blocco nella mia base di codice sembra piuttosto inutile. – Riggy

+0

@Riggy, è sicuramente ridondante. – Mike

-3

Scopo. Qualsiasi variabile dichiarata nel blocco esce dall'ambito dopo il blocco. È utile mantenere le variabili con scope minimale.

Inoltre, se si definisce una classe interna anonima, si utilizza questa sintassi per il costruttore.

+0

Non proprio. Sarebbe stato uno scopo, se fosse stato all'interno di un corpo metodico. Questo è nel corpo della classe, al di fuori dei metodi. Leggi altre risposte. –

+0

-1 Questa è una risposta errata.Nel caso in cui è un blocco di inizializzazione. –

16

Si chiama initializer block.

blocco di inizializzazione per le variabili di istanza sono proprio come blocco di inizializzazione statico, ma senza la parola chiave static:

{ 
     // whatever code is needed for initialization goes here 
    } 

I blocchi di copie del compilatore Java di inizializzazione in ogni costruttore. Pertanto, questo approccio può essere utilizzato per condividere un blocco di codice tra più costruttori.

+0

Sia tu che Mike avete lasciato risposte eccellenti, grazie a entrambi per i link. Non avevo pensato ai costruttori con sovraccarico multiplo, dato che le varie classi che ho trovato hanno un solo costruttore ciascuno. – Riggy

+0

Un piccolo nitpick - afaik il compilatore non copia il blocco di inizializzazione, aggiunge semplicemente una chiamata dal costruttore al metodo speciale , che è ciò che {} diventa nel file .class. [Il blocco inizializzatore statico diventa il metodo .] –

4

Il tuo predecessore stava ancora imparando.

Questa è la migliore spiegazione che è possibile ottenere. Forse a un certo punto nel tempo era necessario che il codice si dividesse in questo modo. È difficile da dire. Il codice dovrebbe certamente essere scritto come questo, invece:

 
public class ChildClass extends ParentClass { 
    public ChildClass() { 
     inheritedVar = "someVal"; 
    } 
    // rest of code 
} 

Per quanto riguarda il blocco di inizializzazione, il suo scopo è stato dato dagli altri risposte qui. Ho lanciato la mia risposta nel tentativo di rispondere al "perché", che hai richiesto. Sfortunatamente, per la vera risposta, dovresti chiedere al tuo predecessore.

+0

Avevo solo postato la quantità minima di codice per ottenere il mio punto di vista senza gravare sui lettori di SO con il codice spazzatura. Ho incluso solo il costruttore in modo che fosse evidente che esiste un costruttore nel codice e che il blocco senza nome non stava sostituendo il costruttore. Grazie! – Riggy

+0

Nessun problema. Ho rimosso la parte della mia risposta chiedendole. –

+4

Hai ragione che non è il miglior codice. Suggerirei che il predecessore stava imparando. Ci sono così tanti sviluppatori che chiamano altri idioti sviluppatori, e tutto ciò che fa è far sì che le persone nascondano i propri errori in modo che non vengano imbarazzati o peggio, licenziati. Preferirei vedere "Il tuo predecessore stava ancora imparando a codificare bene". Sono in missione per creare ambienti sicuri per gli sviluppatori per imparare i giusti modi di fare le cose, e sento fortemente che StackOverflow dovrebbe essere uno di loro - saresti disposto ad aiutare e cambiare la lingua che usi? – Lunivore

Problemi correlati