Convenzione di denominazione: campi finali (non statici)


23

Oggi ho avuto una discussione con un collega sulla denominazione dei finalcampi nelle classi Java.

Nei suoi finalcampi opionion dovrebbero essere considerati costanti poiché i loro valori non cambieranno dopo la creazione dell'istanza.

Ciò porterebbe alla seguente convenzione di denominazione per i finalcampi:

public class Foo {
    private static final String BLA_BLA = "bla";

    private final String BAR_BATZ;

    ...
}

A mio avviso, solo i static finalcampi dovrebbero essere considerati costanti mentre i campi che sono solo finaldovrebbero seguire la consueta convenzione di denominazione camelCase.

public class Foo {
    private static final String BLA = "bla";

    private final String barBatz;

    ...
}

Ora sono un po 'incerto poiché è un programmatore molto più esperto di me e di solito sono d'accordo con le sue opinioni e lo considero un ottimo sviluppatore.

Qualche input su questo?


I tuoi esempi non sono costanti; non hai assegnato alcun valore al momento della compilazione. Ergo, non seguono le convenzioni di denominazione per le costanti.
Robert Harvey,

@RobertHarvey Grazie, hai ragione. Lo ...scopo era quello di simboleggiare ogni possibile costruttore che imposta il finalcampo, ma questo ovviamente non è possibile per il static finalcampo.
Sascha Wolf,

1
@Zeeker potresti essere interessato ai static { }blocchi che possono essere usati per impostare i campi statici all'interno di una classe una volta caricata la classe. Correlato Lavorare con il costruttore statico in Java .

@RobertHarvey Ho familiarità con quelli. Ma grazie comunque.
Sascha Wolf,

1
Direi che poiché la variabile appartiene a un'istanza, sarà diversa da istanza a istanza, quindi non si applica come costante. Vorrei usare la custodia per cammello.
Florian F,

Risposte:


20

Sun (e ora Oracle) ha mantenuto un documento intitolato Convenzioni del codice per il linguaggio di programmazione Java . L'ultimo aggiornamento è stato nel '99, ma l'essenza della linea guida di stile sopravvive.

Il capitolo 9 tratta le convenzioni di denominazione.

Per un tipo di identificatore di "costanti":

I nomi delle variabili dichiarate costanti di classe e delle costanti ANSI devono essere tutte maiuscole con parole separate da caratteri di sottolineatura ("_"). (Le costanti ANSI dovrebbero essere evitate, per facilitare il debug.)

Gli esempi forniti:

static final int MIN_WIDTH = 4;

static final int MAX_WIDTH = 999;

static final int GET_THE_CPU = 1;

In un documento più recente - è scivolato lì dentro. Dalle variabili (Tutorial Java> Apprendimento della lingua Java> Nozioni di base sulla lingua :

Se il nome che scegli è composto da una sola parola, scrivi quella parola in tutte le lettere minuscole. Se è composto da più di una parola, scrivere in maiuscolo la prima lettera di ogni parola successiva. I nomi gearRatioe currentGearsono esempi primi di questa convenzione. Se la variabile memorizza un valore costante, come ad esempio static final int NUM_GEARS = 6, la convenzione cambia leggermente, capitalizzando ogni lettera e separando le parole successive con il carattere di sottolineatura. Per convenzione, il carattere di sottolineatura non viene mai utilizzato altrove.

Molti analizzatori statici per Java cercano di imporlo. Ad esempio, checkstyle applica:

Verifica che i nomi delle costanti siano conformi a un formato specificato dalla proprietà format. Una costante è un campo statico e finale o un campo di interfaccia / annotazione, ad eccezione di serialVersionUIDe serialPersistentFields. Il formato è un'espressione regolare e per impostazione predefinita è ^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$.


Questo si riduce davvero alle convenzioni della comunità che scrivono il codice ... e idealmente mantengono lo stesso.

Gli esempi sopra riportati sono riportati come static finalquelli che probabilmente derivano dalle convenzioni C per #definecui, come C, vengono sostituiti nel codice durante la compilazione anziché in fase di esecuzione.

La domanda che allora dovrebbe essere posta è "si sta comportando come una costante? O si sta comportando come un campo di scrittura una volta?" - e quindi seguendo le convenzioni di conseguenza. La cartina di tornasole per una domanda del genere sarebbe "Se dovessi serializzare l'oggetto, includeresti il ​​campo finale?" Se la risposta è che è una costante, trattala come tale (e non serializzarla). D'altra parte, se fa parte dello stato dell'oggetto che dovrebbe essere serializzato, allora non è una costante.

In ogni caso, è importante attenersi allo stile del codice per quanto giusto o sbagliato sia. Problemi peggiori scaturiscono da convenzioni incoerenti all'interno di un progetto piuttosto che semplicemente qualcosa che offende l'occhio. Prendi in considerazione la possibilità di ottenere alcuni strumenti di analisi statica e configurarli per mantenere la coerenza.



@RobertHarvey Potrei concepire alcune situazioni in cui un campo di istanza si comporta come una costante. Una fabbrica, ad esempio, popola qualcosa che altrimenti sarebbe una costante nell'oggetto ... anche se questi arrivano a esempi piuttosto inventati che mi fanno male alla testa solo pensando al perché uno lo farebbe.

Grazie per questa risposta dettagliata. La cartina di tornasole sulla serializzazione dell'oggetto ha fatto il patto per me.
Sascha Wolf

Un collega ha recentemente affermato che, una volta, i redattori non erano molto bravi nell'evidenziare finali statici / statici ecc., Quindi questa convenzione di denominazione era importante. In questi giorni gli IDE sono abbastanza buoni, quindi possiamo forse creare nomi più belli per loro, ad esempio: MinWidthinvece di MIN_WIDTH. Un'altra domanda è: che dire dei logger finali statici? Li chiami LOG/ LOGGERo log/ logger. Personalmente, logsembra meglio in linea con il codice, ma quando l'incoerenza è accettabile, se non del tutto?
ndtreviv,

5

BAR_BATZnon è una costante in questo esempio. I costruttori di Foopossono impostarlo su valori diversi a livello di oggetto. Per esempio

public class Foo {
    private final String BAR_BATZ;

    Foo() {
       BAR_BATZ = "ascending";
    } 

    Foo(String barBatz) {
       BAR_BATZ = barBatz;
    }
}
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.