Affidarsi all'inizializzazione di campo predefinita: lo stile di programmazione è errato? [chiuso]


20

Mi è stato dato un link alla documentazione ufficiale dell'oracolo: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

dove si dice:

Valori standard

Non è sempre necessario assegnare un valore quando viene dichiarato un campo. I campi dichiarati ma non inizializzati verranno impostati su un valore predefinito ragionevole dal compilatore. In generale, questo valore predefinito sarà zero o nullo, a seconda del tipo di dati. Affidarsi a tali valori predefiniti, tuttavia, è generalmente considerato un cattivo stile di programmazione.

Voglio sottolineare questa parte:

Affidarsi a tali valori predefiniti, tuttavia, è generalmente considerato un cattivo stile di programmazione.

Ma, oh ragazzo, questa è, direi, una parte fondamentale della specifica del linguaggio sapendo che le variabili di istanza hanno valori predefiniti. Perché mai questa è una cattiva pratica di programmazione se è ampiamente usata anche nel codice sorgente delle librerie Java SE?


5
Huh. Non ho mai saputo che quella frase fosse lì. In realtà considero una buona pratica fare affidamento su di essi. private int count = 0;è il codice che non fa nulla e il codice che non fa nulla è disordinato. È come importare classi da java.lang o dichiarare una classe con extends Object.
VGR,

2
... o con un public abstractmetodo in un'interfaccia.
mumpitz,

1
cosa c'è di sbagliato nell'astratto pubblico?
John Keates,

1
Un pezzo del puzzle può provenire dal C ++. È una lingua popolare e la sua gestione dell'inizializzazione predefinita contro zero è una fonte continua di bug. In C ++, è una cattiva idea fare affidamento sulle impostazioni predefinite in tutti i casi tranne quelli più eccezionali. Ciò potrebbe essere trapelato a Java culturalmente.
Cort Ammon,

@JohnKeates - Il mio Java è un po 'arrugginito, ma i privatemetodi in un'interfaccia non avrebbero senso e abstractsono impliciti.
Scott Smith,

Risposte:


6

Il testo citato è:

"Affidarsi a tali valori predefiniti, tuttavia, è generalmente considerato un cattivo stile di programmazione."

Cinicamente: "si ritiene generalmente che" sia spesso un modo per dire che l'autore non ha cercato di trovare una fonte autorevole per la dichiarazione presentata.

In questo caso l'affermazione è chiaramente discutibile. Prova: 5 su 5 Java Style Guides campionati NON dicono nulla sull'opportunità o meno di fare affidamento sui valori predefiniti:

(Nota, la mia metodologia per il campionamento è stata quella di esaminare i primi 5 risultati di ricerca distinti di Google per "guida allo stile java". Quindi ho cercato ogni documento come "predefinito". Questa non è un'analisi approfondita, ma serve a chiarire il mio punto. )


OK. Quindi aiuta davvero la leggibilità del codice Java?

Questo è discutibile.

Da un lato, un programmatore Java alle prime armi che non ha imparato l'inizializzazione predefinita può essere sconcertato da dove provengono gli zeri o i null. Ma se si preoccupano di cercare un'inizializzazione esplicita e scoprono che non ce n'è una, ciò dovrebbe essere sufficiente per far loro leggere un tutorial o un libro per scoprire l'inizializzazione predefinita. (Spereresti!)

D'altra parte, normalmente non ci aspettiamo che i programmatori Java alle prime armi mantengano basi di codice di produzione. Per un programmatore Java esperto un'inizializzazione ridondante non migliora la leggibilità. È (al massimo) rumore.

A mio avviso, l'unica cosa che si ottiene con un'inizializzazione ridondante di un campo è segnalare a un futuro lettore del codice che hai pensato al valore iniziale. (Come espresso da @GhostCat, l'inizializzazione predefinita non comunica l'intento.)

Ma al contrario, se fossi quel lettore, non mi fiderei necessariamente del pensiero dell'autore del codice. Quindi anche il valore di questo "segnale" è discutibile.


E l'affidabilità?

In Java non fa differenza. JLS specifica che l'inizializzazione predefinita si verifica per i campi. E viceversa, per le variabili locali è un errore di compilazione tentare di utilizzare una variabile che non è stata definitivamente inizializzata.

In breve, il comportamento di runtime di una variabile non inizializzata esplicitamente è del tutto prevedibile.

Al contrario, in linguaggi come C o C ++ in cui le variabili potrebbero non essere inizializzate, il comportamento non è specificato e può causare arresti anomali e differenze di comportamento su piattaforme diverse. Il caso di inizializzare sempre esplicitamente le variabili è molto più forte qui.


Che dire delle prestazioni?

Non dovrebbe fare alcuna differenza. Il compilatore JIT dovrebbe essere in grado di trattare un'inizializzazione ridondante e l'inizializzazione predefinita come uguali.


19

Semplice: basarsi su valori predefiniti non comunica l'intento.

Volevi davvero che quel campo iniziasse con 0 o hai dimenticato di assegnare un valore ?!

E, naturalmente, un riferimento null è la metà delle due cose che è necessario imbattersi in un'eccezione nullpointer.

Infine, l'utilizzo dei valori predefiniti implica che hai campi non finali. Che eviti dove possibile.

L'unico argomento contrario è: perché scrivere cose che non è necessario? Ma penso che la tromba elencata svantaggi che, assegnando esplicitamente 0 a un campo, è meglio che lasciarlo al compilatore.


3
vale a dire re: non comunicare l'intento - Cosa succede se "Manny the maintainer" sta guardando il tuo codice e non sa quale sia l'impostazione predefinita per un tipo di dati specifico. Sta assumendo che sia 0 quando è veramente NULL e che è l'intero bug su un controllo === (o qualunque sia il controllo equivalente di uguaglianza per valore e tipo è in java, equals ()?). Ore di ricerca (per un programmatore inesperto) potrebbero essere il risultato di qualcosa di così semplice. PS sta cercando di interpretare l'avvocato del diavolo. Dico di usare le impostazioni predefinite tutto il giorno (anche se non lo faccio mai) e ottenere persone più intelligenti (o almeno una maggiore attenzione ai dettagli) per mantenere il tuo codice.
TCooper,

@TCooper quando mannie il manutentore sa così poco di Java, non ha affari a toccare il codice Java del mondo reale. Ma sono d'accordo con l'idea di fondo. Rende le cose più difficili per i neofiti.
GhostCat saluta Monica C. il

12

Perché mai questa è una cattiva pratica di programmazione

L'idea è se si fa affidamento su un valore predefinito, quindi non è immediatamente chiaro a chiunque legga il codice se lo si è lasciato deliberatamente come valore predefinito o se si è semplicemente dimenticato di assegnarlo.

... se è ampiamente utilizzato anche nel codice sorgente delle librerie Java SE ??

Il codice sorgente Java non è davvero qualcosa su cui dovresti fare affidamento come esempio di pratica di codifica esemplare. Ci sono molti casi in cui tali regole vengono violate (a volte intenzionalmente per piccoli miglioramenti delle prestazioni, a volte accidentalmente o perché lo stile accettato è cambiato nel corso degli anni).


2
Questo probabilmente è giusto, anche se non sono d'accordo.
VGR,

3
@VGR Per quanto tendo a concordare con l'affermazione secondo cui fare affidamento su valori predefiniti non è ottimale, sono stato attento a formularlo in modo neutro per tale motivo. La qualità del codice è soggettiva e sono ben consapevole che questa non è affatto una visione universalmente condivisa.
Michael Berry,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.