2010-02-18 11 views
13

Recentemente ho visto questo costruttore in una classe:C'è un motivo per codificare esplicitamente un costruttore predefinito quando non ci sono altri costruttori?

public MyClass(){ } 

Non c'erano altri costruttori.

C'è una ragione per questo? Java crea automaticamente un costruttore predefinito, quindi perché dichiararne uno esplicitamente? Oppure questa è considerata una buona pratica allo stesso modo di usare le parentesi per le istruzioni con istruzione singola se nel caso in cui altri costruttori vengano aggiunti successivamente e si dimentichi che non si dispone di un valore predefinito ...?

+2

Una nota sulla semantica, il nome corretto per tale costruttore è un "costruttore senza argomenti". È solo un costruttore "predefinito" quando il compilatore lo genera automaticamente per impostazione predefinita. –

risposta

16

Un paio di punti minori che probabilmente non sono il motivo per cui l'hai visto in questo caso.

  • Ti dà qualcosa su cui impostare un punto di interruzione.
  • Si potrebbe rendere non pubblico

Per quanto riguarda "nel caso in cui vengono aggiunti in seguito altri costruttori e si dimentica che non si dispone di un default" - che potrebbe essere una ragione, suppongo. Ma se fosse stato aggiunto un costruttore non predefinito, qualsiasi codice che usasse il costruttore predefinito non sarebbe stato compilato, quindi il tizio che aggiungeva il nuovo costrutore avrebbe generalmente bisogno di aggiungere anche una definizione per il ctor predefinito.

Quindi, ancora una volta, non riesco a pensare ad alcun danno particolare nell'avere definito il codificatore vuoto (anche se ora che l'ho digitato, ho la sensazione che qualcuno potrebbe indicare qualche angolo di C++ dove potrebbe morderti).

+2

Potrebbe essere stato creato automaticamente da un IDE o lasciato dall'eliminazione di un costruttore non predefinito. Inoltre, sono stato conosciuto per creare tali costruttori su classi che so necessitano di un valore predefinito (ad esempio a causa di alcuni requisiti di serializzazione o di associazione dei dati) e non voglio essere morso da un problema quando un secondo costruttore viene eseguito successivamente. –

+3

codice che viene scritto solo per "nel caso in cui ho bisogno di aggiungere il codice per qualcos'altro dopo" è un codice odore –

+0

@Michael - :) per impostare un punto di interruzione ... Anche se si potrebbe davvero impostare un punto di interruzione sulla classe (pubblico classe MyClass ...). @matt b - è sempre? Ho spesso sentito persone sostenere le parentesi attorno a if a singola frase perché si potrebbero aggiungere altre affermazioni in un secondo momento, supponendo che verranno eseguite come parte del if, generando così un bug sottile. Questo esempio è probabilmente un po 'più inverosimile e dovrebbe essere facile da cogliere. – froadie

6

Non svolge alcun ruolo e può essere eliminato in modo sicuro.

1

perché credete nella seconda frase di the zen of python:

Esplicito è meglio che implicita.

+0

È vero? Posso pensare a molte fastidiose conseguenze di una simile affermazione ... (Sempre estendendo in modo esplicito Object, per esempio.) – froadie

+0

Direi che lo è. Nel peggiore dei casi, sarai prolisso, ma non può fare alcun danno e metti tutto di fronte a te quando cerchi un bug o cerchi di capire il quadro generale. Nel tuo caso specifico, non ho mai amato questo zucchero sintattico: se la mia classe può produrre istanze, ha bisogno di un costruttore, quindi perché nasconderlo? La mia antipatia può derivare dal contrasto tra la verbosità generale di Java e, improvvisamente, l'offerta di bonus speciali: il costruttore è incluso. Non c'è vergogna per avere un costruttore, giusto? – Hubert

0

Correggetemi se ho torto (non ho fatto Java in un attimo), ma questo non impedisce una chiamata al costruttore genitore? In questo caso il ragionamento è ovviamente che il genitore sta per fare qualcosa automaticamente che non vuoi che accada in questa classe.

+5

No, la chiamata 'super()' è ancora implicita. Non puoi evitare di chiamare un costruttore genitore in Java. –

+0

@mmyers - anche in un costruttore di parametri? O solo nel predefinito? – froadie

+4

se un costruttore non richiama esplicitamente un costruttore di superclasse, il compilatore Java inserisce automaticamente una chiamata al costruttore no-argument della superclasse. Se la super classe non ha un costruttore senza argomenti, si otterrà un errore in fase di compilazione. L'oggetto ha un tale costruttore, quindi se Object è l'unica superclasse, non ci sono problemi. – LB40

3

Ecco cosa Java Language Specification dice:

Se una classe non contiene costruttore dichiarazioni, poi un costruttore di default che non richiede parametri viene fornita automaticamente:

  • Se la classe essere dichiarato è l'oggetto di classe primordiale, quindi il costruttore predefinito ha un corpo vuoto.
  • In caso contrario, il costruttore predefinito non accetta parametri e richiama semplicemente il costruttore della superclasse senza argomenti .

Quindi il costruttore predefinito verrà comunque creato. Non ha senso scriverlo se non lo fai. dovere.

IMO si dovrebbe fare solo se si desidera modificare il livello di visibilità del costruttore, cioè renderlo privato o di un pacchetto protetto

0

mi è stato insegnato che un costruttore di default pubblico è stato richiesto dalla specifica di fagioli java .. La pagina di wikipedia http://en.wikipedia.org/wiki/Java_Bean lo elenca anche come un requisito.

D'altra parte, ho guardato il sito Sun/Oracle e non sono riuscito a trovarlo. Vedi http://java.sun.com/developer/onlineTraining/Beans/Beans1/simple-definition.html

+0

Sì, ma esiste implicitamente, il che dovrebbe andare bene per le specifiche dei bean java. Non credo che i java bean richiedano di crearne uno in modo esplicito, ma ha bisogno che esista – froadie

3

Anche se non si ottiene nulla aggiungendo esplicitamente il costruttore a livello tecnico, ci sono potenzialmente motivi per farlo. Uno sarebbe se la classe fosse istanziata tramite riflessione, potreste voler mettere della documentazione sul costruttore predefinito per indicare che è richiesta anche se l'aggiunta di un nuovo costruttore non causerebbe un errore di compilazione.

Un altro è che alcuni standard di codifica lo preferiscono per indicare esplicitamente il pensiero su quale tipo di costruttore questa classe dovrebbe avere.

+0

+1 per "la classe viene istanziata tramite riflessione": alcuni framework possono farlo e non avere un costruttore no-arg li infrangerà (in fase di esecuzione :-(). Ma questo dovrebbe * sicuramente * essere documentato nel costruttore javadocs. – sleske

+0

Nel caso in cui la classe sia istanziata tramite riflessione, preferirei un caso di test per garantire che nessuno si rompa accidentalmente questo aspetto –

0

V'è in realtà un buon motivo per includere non menzionato in queste risposte:

Se l'esistenza di un costruttore senza argomenti è esplicitamente parte del contratto per l'oggetto, allora dovrebbe essere esplicitamente .

Se si intende esplicitamente per il client la sottoclasse del codice, come ad es. Java Swing, quindi è una buona idea rendere esplicitamente un costruttore no-arg accessibile, anche se non ci sono altri costruttori. Altrimenti, se un altro programmatore, nella sua saggezza, decide di creare un altro costruttore, il nuovo costruttore esplicito rimuoverà il costruttore implicito no-arg e interromperà il codice client.

Se il codice è sottoclassato nella propria base di codice, questo verrà visualizzato come errore del compilatore, ma se il codice deve essere pubblicato come jar e sottoclassato dal client non ci sarà alcun errore del compilatore .

Ovviamente, si potrebbe obiettare che se la sua parte del contratto dovresti avere un test di junit per questo, e avresti ragione! Ma se stai lavorando su una base di codice di grandi dimensioni in cui i test richiedono ore di esecuzione per la tua build giornaliera, rompendo la tua build giornaliera perché hai dimenticato di dover fare esplicitamente un costruttore no arg quando aggiungi un costruttore è un enorme spreco di tempo quando un costruttore esplicito e un commento avrebbe evitato qualsiasi possibilità di errore.

L'obiettivo del buon codice è di rendere il più semplice possibile per un altro sviluppatore di modificarlo senza errori!

+0

* "Altrimenti , se un altro programmatore, nella sua saggezza, decide di fare un altro costruttore, "* ... Se ha una classe senza alcun costruttore, allora dovrebbe essere in grado di capire l'impatto sul codice, se crea il primo (explizit) costruttore (solo i miei due centesimi) – Tom

Problemi correlati