Convention de dénomination: champs finaux (non statiques)

23

Aujourd'hui, j'ai eu une discussion avec un collègue sur la dénomination des finalchamps dans les classes Java.

Dans son opionion, les finalchamps doivent également être considérés comme des constantes car leurs valeurs ne changeront pas après la création de l'instance.

Cela conduirait à la convention de dénomination suivante pour les finalchamps:

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

    private final String BAR_BATZ;

    ...
}

À mon avis, seuls les static finalchamps doivent être considérés comme des constantes tandis que les champs qui le sont finaldoivent suivre la convention de dénomination camelCase habituelle.

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

    private final String barBatz;

    ...
}

Maintenant, je suis un peu incertain car il est un programmeur beaucoup plus expérimenté que moi et je suis généralement d'accord avec ses opinions et le considère comme un très bon développeur.

Des commentaires à ce sujet?

Sascha Wolf
la source
Vos exemples ne sont pas des constantes; vous ne leur avez attribué aucune valeur au moment de la compilation. Ergo, ils ne suivent pas les conventions de dénomination des constantes.
Robert Harvey
@RobertHarvey Merci, vous avez raison. Le ...était censé symboliser tout constructeur possible qui définit le finalchamp, mais ce n'est évidemment pas possible pour le static finalchamp.
Sascha Wolf
1
@Zeeker, vous pouvez être intéressé par les static { }blocs qui peuvent être utilisés pour définir des champs statiques dans une classe une fois lorsque la classe est chargée. Associé Travailler avec un constructeur statique en Java .
@RobertHarvey, je les connais. Mais merci quand même.
Sascha Wolf
1
Je dirais que puisque la variable appartient à une instance, elle sera différente d'une instance à l'autre, donc elle ne s'applique pas en tant que constante. J'utiliserais un étui à chameau.
Florian F

Réponses:

20

Sun (et maintenant Oracle) a maintenu un document intitulé Conventions de code pour le langage de programmation Java . La dernière mise à jour a eu lieu en 1999, mais l'essence de la ligne de guide de style persiste.

Le chapitre 9 couvre les conventions de dénomination.

Pour un type d'identifiant de «constantes»:

Les noms des variables déclarées constantes de classe et des constantes ANSI doivent être tous en majuscules avec des mots séparés par des traits de soulignement ("_"). (Les constantes ANSI doivent être évitées, pour faciliter le débogage.)

Les exemples donnés:

static final int MIN_WIDTH = 4;

static final int MAX_WIDTH = 999;

static final int GET_THE_CPU = 1;

Dans un document plus récent - son glissé là-dedans. From Variables (Les tutoriels Java> Apprendre le langage Java> Bases du langage :

Si le nom que vous choisissez se compose d'un seul mot, épelez ce mot dans toutes les lettres minuscules. S'il se compose de plusieurs mots, mettez en majuscule la première lettre de chaque mot suivant. Les noms gearRatioet currentGearles exemples principaux de cette convention. Si votre variable stocke une valeur constante, telle que static final int NUM_GEARS = 6, la convention change légèrement, mettant en majuscule chaque lettre et séparant les mots suivants par le caractère de soulignement. Par convention, le caractère de soulignement n'est jamais utilisé ailleurs.

De nombreux analyseurs statiques pour Java cherchent à appliquer cela. Par exemple, le style de contrôle applique:

Vérifie que les noms constants sont conformes à un format spécifié par la propriété format. Une constante est un champ statique et final ou un champ d'interface / d'annotation, sauf serialVersionUIDet serialPersistentFields. Le format est une expression régulière par défaut ^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$.


Cela se résume vraiment aux conventions de la communauté écrivant le code ... et idéalement le gardant le même.

Les exemples ci-dessus sont donnés comme static finalceux qui sont probablement dérivés des conventions C pour #define- qui, comme C, sont remplacées dans le code lors de la compilation plutôt qu'à l'exécution.

La question qui devrait alors être posée est "est-ce que cela se comporte comme une constante? Ou est-ce comme un champ à écriture unique?" - puis suivre les conventions en conséquence. Le test décisif pour une telle question serait "Si vous étalonniez l'objet, incluriez-vous le champ final?" Si la réponse est qu'il s'agit d'une constante, traitez-la comme telle (et ne la sérialisez pas). D'un autre côté, si cela fait partie de l'état de l'objet qui devrait être sérialisé, alors ce n'est pas une constante.

Quoi qu'il en soit, il est important de s'en tenir au style de code, qu'il soit juste ou faux. Les problèmes les plus graves surgissent de conventions incohérentes dans un projet plutôt que simplement quelque chose qui choque l'œil. Envisagez d'obtenir des outils d'analyse statique et de les configurer pour maintenir la cohérence.


la source
@RobertHarvey Je pourrais concevoir certaines situations où un champ d'instance se comporte comme une constante. Une usine, par exemple, peuplant quelque chose qui autrement serait une constante dans l'objet ... bien que ceux-ci arrivent à des exemples plutôt artificiels qui me font mal à la tête juste en pensant à pourquoi on le ferait.
Merci pour cette réponse détaillée. Le test décisif sur la sérialisation de l'objet a fait l'affaire pour moi.
Sascha Wolf
Un collègue a fait valoir récemment l'argument valable de dire que, une fois, les éditeurs n'étaient pas très bons pour mettre en évidence les finales statiques / statiques, etc., donc cette convention de dénomination était importante. De nos jours, les IDE sont assez bons, donc nous pouvons peut-être leur donner de plus beaux noms, par exemple: MinWidthau lieu de MIN_WIDTH. Une autre question est: qu'en est-il des enregistreurs finaux statiques? Les appelez-vous LOG/ LOGGERou log/ logger. Personnellement, logsemble mieux en ligne avec le code, mais quand l'incohérence est-elle acceptable, le cas échéant?
ndtreviv
5

BAR_BATZn'est pas une constante dans cet exemple. Les constructeurs de Foopeuvent le définir sur différentes valeurs au niveau de l'objet. Par exemple

public class Foo {
    private final String BAR_BATZ;

    Foo() {
       BAR_BATZ = "ascending";
    } 

    Foo(String barBatz) {
       BAR_BATZ = barBatz;
    }
}
Kirby
la source