Convention de nommage Java pour les variables finales statiques

il y a une règle qui dit:

Les noms représentant des constantes (variables finales) doivent être tous en majuscule en utilisant le caractère de soulignement pour séparer les mots (extrait de http://geosoft.no/development/javastyle.html )

cela fonctionne très bien pour les types primitifs comme int ou les chaînes de caractères:

private static final int MAX_COUNT = 10; 

Mais qu’en est-il des types non primitifs? Dans la plupart des cas, j’ai vu ce qui suit:

 private static final Logger log = Logger.getLogger(MyClass.class); 

ou en singletons, où la variable d’instance n’est pas en majuscule.

La question est de savoir quelle est la bonne façon de déclarer ces types de variables (comme le journal et l’instance).

C’est toujours une constante . Voir le JLS pour plus d’informations concernant la convention de dénomination des constantes. Mais en réalité, tout est une question de préférence.


Les noms des constantes dans les types d’interface doivent être, et les variables final des types de classe peuvent être classiquement une séquence d’un ou plusieurs mots, acronymes ou abréviations, toutes en majuscules, avec des composants séparés par des caractères de soulignement "_" . Les noms constants doivent être descriptifs et non inutilement abrégés. Conventionnellement, ils peuvent être n’importe quelle partie appropriée du discours. MIN_VALUE , MAX_VALUE , MIN_RADIX et MAX_RADIX de la classe Character exemples de noms de constantes.

Un groupe de constantes qui représentent des valeurs alternatives d’un ensemble, ou, moins fréquemment, des bits de masquage dans une valeur entière, sont parfois utilement spécifiés avec un acronyme commun comme préfixe de nom, comme dans:

 interface ProcessStates { int PS_RUNNING = 0; int PS_SUSPENDED = 1; } 

L’obscurcissement impliquant des noms constants est rare:

  • Les noms de constante n’ont généralement pas de minuscules, ils ne masqueront donc pas normalement les noms des paquets ou des types, ni ne masqueront normalement les champs, dont les noms contiennent généralement au moins une lettre minuscule.
  • Les noms de constante ne peuvent pas masquer les noms de méthode, car ils sont distingués syntaxiquement.

Le dialog à ce sujet semble être l’antithèse de la conversation sur l’ interface dénomination et abstract classes abstract . Je trouve cela alarmant et je pense que la décision va beaucoup plus loin que de simplement choisir une convention de dénomination et de l’utiliser toujours avec static final .

Résumé et interface

Lorsque vous nommez des interfaces et des classes abstraites, la convention acceptée a évolué pour ne pas préfixer ou suffixer votre abstract class ou votre interface avec des informations d’identification indiquant qu’elle est autre chose qu’une classe.

 public interface Reader {} public abstract class FileReader implements Reader {} public class XmlFileReader extends FileReader {} 

On dit que le développeur n’a pas besoin de savoir que les classes ci-dessus sont abstract ou une interface .

Finale statique

Ma préférence personnelle et ma conviction sont que nous devrions suivre une logique similaire en faisant référence aux variables static final . Au lieu de cela, nous évaluons son utilisation pour déterminer comment le nommer. Il semble que l’argument tout en majuscule soit quelque chose qui a été quelque peu adopté à l’aveuglette à partir des langages C et C ++. À mon avis, cela ne justifie pas de continuer la tradition en Java.

Question d’intention

Nous devrions nous demander quelle est la fonction de la static final dans notre propre contexte. Voici trois exemples de la façon dont la static final peut être utilisée dans différents contextes :

 public class ChatMessage { //Used like a private variable private static final Logger logger = LoggerFactory.getLogger(XmlFileReader.class); //Used like an Enum public class Error { public static final int Success = 0; public static final int TooLong = 1; public static final int IllegalCharacters = 2; } //Used to define some static, constant, publicly visible property public static final int MAX_SIZE = Integer.MAX_VALUE; } 

Pourriez-vous utiliser toutes les majuscules dans les trois scénarios? Absolument, mais je pense qu’on peut dire que cela détruirait l’objective de chacun. Alors, examinons chaque cas individuellement.


But: Variable privée

Dans le cas de l’exemple de l’ Logger ci-dessus, le consignateur est déclaré comme privé et ne sera utilisé que dans la classe ou éventuellement dans une classe interne. Même s’il a été déclaré protected ou protected , son utilisation est la même:

 public void send(final Ssortingng message) { logger.info("Sending the following message: '" + message + "'."); //Send the message } 

Ici, peu importe que logger soit une variable membre static final . Cela pourrait simplement être une variable d’instance final . Nous ne soaps pas Nous n’avons pas besoin de savoir. Tout ce que nous avons besoin de savoir, c’est que nous enregistrons le message dans le journal que l’instance de classe a fourni.

 public class ChatMessage { private final Logger logger = LoggerFactory.getLogger(getClass()); } 

Vous ne le LOGGER pas LOGGER dans ce scénario, alors pourquoi devriez-vous le nommer tout en majuscule s’il s’agissait d’une version static final ? Son contexte ou intention est le même dans les deux cas.

Note: J’ai inversé ma position sur la visibilité des package car elle ressemble plus à une forme d’access public , limitée au niveau des package .


But: Enum

Maintenant, vous pourriez dire, pourquoi utilisez-vous static final entiers static final comme enum ? C’est une discussion qui continue d’évoluer et je dirais même semi-controversée, alors je vais essayer de ne pas faire dérailler cette discussion en m’y aventurant. Cependant, il serait suggéré que vous puissiez implémenter le modèle enum accepté suivant:

 public enum Error { Success(0), TooLong(1), IllegalCharacters(2); private final int value; private Error(final int value) { this.value = value; } public int value() { return value; } public static Error fromValue(final int value) { switch (value) { case 0: return Error.Success; case 1: return Error.TooLong; case 2: return Error.IllegalCharacters; default: throw new IllegalArgumentException("Unknown Error value."); } } } 

Il existe des variantes de ce qui précède pour atteindre le même objective, à savoir permettre la conversion explicite d’un enum->int et d’un enum->int int->enum . Dans le cadre de la diffusion de ces informations sur un réseau, la sérialisation Java native est tout simplement trop verbeuse. Un simple int , short ou byte pourrait économiser une bande passante considérable. Je pourrais me plonger dans une longue comparaison entre les avantages et les inconvénients de l’ enum vs static final int impliquant la sécurité de type, la lisibilité, la maintenabilité, etc .; heureusement, cela dépasse le cadre de cette discussion.

L’essentiel est que, parfois, static final int sera utilisé comme structure de style enum .

Si vous pouvez vous amener à accepter que la déclaration ci-dessus est vraie , nous pouvons poursuivre avec une discussion sur le style. En déclarant une enum , le style accepté indique que nous ne faisons pas ce qui suit:

 public enum Error { SUCCESS(0), TOOLONG(1), ILLEGALCHARACTERS(2); } 

Au lieu de cela, nous faisons ce qui suit:

 public enum Error { Success(0), TooLong(1), IllegalCharacters(2); } 

Si votre bloc static final de nombres entiers sert de enum vrac, pourquoi devriez-vous utiliser une convention de dénomination différente? Son contexte ou intention est le même dans les deux cas.


But: Propriété statique, constante et publique

Ce cas d’utilisation est peut-être le plus trouble et le plus discutable de tous. L’exemple d’utilisation statique de taille constante est celui qui est le plus souvent rencontré. Java supprime le besoin de sizeof() , mais il est parfois important de savoir combien d’octets une structure de données occupera.

Par exemple, considérez que vous écrivez ou lisez une liste de structures de données dans un fichier binary et que le format de ce fichier binary exige que la taille totale du bloc de données soit insérée avant les données réelles. Cela est courant pour qu’un lecteur sache à quel moment les données s’arrêtent dans le scénario et que celles-ci sont plus nombreuses et non liées. Considérez le format de fichier composé suivant:

 File Format: MyFormat (MYFM) for example purposes only [int filetype: MYFM] [int version: 0] //0 - Version of MyFormat file format [int dataSize: 325] //The data section occupies the next 325 bytes [int checksumSize: 400] //The checksum section occupies 400 bytes after the data section (16 bytes each) [byte[] data] [byte[] checksum] 

Ce fichier contient une liste d’objects MyObject sérialisés dans un stream d’octets et écrits dans ce fichier. Ce fichier contient 325 octets d’objects MyObject , mais sans connaître la taille de chaque object MyObject vous n’avez aucun moyen de savoir quels octets appartiennent à chaque object MyObject . Vous définissez donc la taille de MyObject sur MyObject :

 public class MyObject { private final long id; //It has a 64bit identifier (+8 bytes) private final int value; //It has a 32bit integer value (+4 bytes) private final boolean special; //Is it special? (+1 byte) public static final int SIZE = 13; //8 + 4 + 1 = 13 bytes } 

La structure de données MyObject occupera 13 octets lorsqu’elle sera écrite dans le fichier tel que défini ci-dessus. Sachant cela, lors de la lecture de notre fichier binary, nous pouvons déterminer dynamicment combien d’objects MyObject suivent dans le fichier:

 int dataSize = buffer.getInt(); int totalObjects = dataSize / MyObject.SIZE; 

Cela semble être le cas d’utilisation typique et l’argument pour toutes les constantes static final majuscules, et je suis d’accord que dans ce contexte, toutes les majuscules ont un sens. Voici pourquoi:

Java n’a pas de classe de struct comme le langage C, mais une struct est simplement une classe avec tous les membres publics et aucun constructeur. C’est simplement une struct données. Donc, vous pouvez déclarer une class comme struct :

 public class MyFile { public static final int MYFM = 0x4D59464D; //'MYFM' another use of all uppercase! //The struct public static class MyFileHeader { public int fileType = MYFM; public int version = 0; public int dataSize = 0; public int checksumSize = 0; } } 

Permettez-moi de préfacer cet exemple en déclarant que personnellement, je ne vais pas parsingr de cette manière. Je suggère plutôt une classe immuable qui gère l’parsing en interne en acceptant un ByteBuffer ou les 4 variables comme arguments de constructeur. Cela dit, en accédant (paramètre dans ce cas) aux membres de cette struct , cela ressemblerait à ceci:

 MyFileHeader header = new MyFileHeader(); header.fileType = buffer.getInt(); header.version = buffer.getInt(); header.dataSize = buffer.getInt(); header.checksumSize = buffer.getInt(); 

Celles-ci ne sont ni static ni final , pourtant elles sont exposées publiquement et peuvent être définies directement. Pour cette raison, je pense que lorsqu’un membre static final est exposé publiquement, il est logique de le mettre entièrement en majuscule. C’est la seule fois où il est important de le distinguer des variables publiques et non statiques.

Remarque: même dans ce cas, si un développeur tentait de définir une variable final , il rencontrerait une erreur IDE ou une erreur de compilation.


Résumé

En conclusion, la convention que vous choisissez pour static final variables static final sera votre préférence, mais je crois fermement que le contexte d’utilisation devrait peser lourdement sur votre décision de conception. Ma recommandation personnelle serait de suivre l’une des deux méthodes suivantes:

Méthodologie 1: évaluer le contexte et l’intention [highly subjective; logical] [highly subjective; logical]

  • Si c’est une variable private qui ne peut pas être distinguée d’une variable d’instance private , nommez-la de la même manière. tout en minuscule
  • Si son intention est de servir de type de bloc de valeurs static vrac, nommez-le comme un enum . cas pascal: initial-cap chaque mot
  • Si son intention est de définir des propriétés accessibles au public, constantes et statiques, laissez-les se démarquer en les rendant toutes majuscules.

Méthodologie 2: Privé vs Public [objective; logical] [objective; logical]

La méthodologie 2 condense essentiellement son contexte dans la visibilité et ne laisse aucune place à l’interprétation.

  • S’il est private ou protected il devrait être en minuscule .
  • Si c’est public ou package alors tout devrait être en majuscule .

Conclusion

Voici comment je vois la convention de dénomination des variables static final . Je ne pense pas que ce soit quelque chose qui peut ou devrait être encapsulé dans une seule prise. Je crois que vous devriez évaluer son intention avant de décider comment l’appeler.

Cependant, l’objective principal devrait être d’essayer de restr cohérent tout au long de la scope de votre projet / package. En fin de compte, c’est tout ce que vous avez le contrôle.

(Je m’attends à rencontrer de la résistance, mais j’espère aussi recueillir le soutien de la communauté sur cette approche. Quelle que soit votre position, veuillez restr civile lors de la réprimande, de la critique ou de la reconnaissance de ce choix de style.)

La langue ne se soucie pas. Ce qui est important, c’est de suivre les styles et les conventions établis du projet sur lequel vous travaillez, de sorte que les autres responsables (ou vous, dans cinq mois) aient les meilleures chances de ne pas être confus.

Je pense qu’un nom en majuscule pour un object mutable m’embrouillerait certainement, même si la référence à cet object était stockée dans une variable static final .

Eh bien, c’est une question très intéressante. Je diviserais les deux constantes de votre question en fonction de leur type. int MAX_COUNT est une constante de type primitif tandis que Logger log est un type non primitif.

Lorsque nous utilisons une constante d’un type primitif, nous ne modifions la constante qu’une seule fois dans notre code public static final in MAX_COUNT = 10 et nous accédons simplement à la valeur de la constante ailleurs for(int i = 0; i . C'est la raison pour laquelle nous sums à l'aise avec cette convention.

Bien que dans le cas de types non primitifs, nous initialisons la constante dans un seul endroit private static final Logger log = Logger.getLogger(MyClass.class); , on doit muter ou appeler une méthode sur cette constante ailleurs log.debug("Problem") . Nous, les gars, n'aimons pas mettre un opérateur point après les caractères majuscules. Après tout, nous devons mettre un nom de fonction après l'opérateur point, ce qui va sûrement être un nom de casse-chameau. C'est pourquoi LOG.debug("Problem") serait bizarre.

Même chose avec les types Ssortingng . En général, nous ne modifions pas ou n'appelons pas une méthode sur une constante Ssortingng dans notre code et c'est pourquoi nous utilisons la convention de dénomination des majuscules pour un object de type Ssortingng .

Il n’y a pas de “bonne” manière – il n’y a que des conventions. Vous avez déclaré la convention la plus courante et celle que je suis dans mon propre code: toutes les finales statiques doivent être en majuscules. J’imagine que d’autres équipes suivent d’autres conventions.

Une référence constante à un object n’est pas une constante, c’est juste une référence constante à un object.

private static final n’est pas ce qui définit quelque chose comme étant une constante ou non. C’est juste la manière Java de définir une constante, mais cela ne signifie pas que chaque déclaration private static final été placée pour définir une constante.

Lorsque j’écris private static final Logger je n’essaie pas de définir une constante, j’essaie simplement de définir une référence à un object private (qui n’est pas accessible par d’autres classes), static (c’est une classe niveau variable, aucune instance nécessaire) et final (qui ne peut être atsortingbué qu’une seule fois). Si cela coïncide avec la manière dont Java s’attend à ce que vous déclariez une constante, eh bien, une mauvaise chance, mais cela ne la rend pas constante. Je me moque de ce que dit le compilateur, le sonar ou tout autre gourou Java. Une valeur constante, comme MILLISECONDS_IN_A_SECOND = 1000 est une chose, et une référence constante à un object en est une autre.

L’or est connu pour briller, mais tout ce qui brille n’est pas de l’or.

A mon avis, une variable “constante” est souvent un détail d’implémentation et ne justifie pas nécessairement des conventions d’appellation différentes. Cela peut aider à la lisibilité, mais cela peut aussi le blesser dans certains cas.

Ces variables sont des constantes, c’est-à-dire qu’elles sont private static final qu’elles soient nommées en majuscules ou non. La convention tout en majuscules rend plus évident que ces variables sont censées être des constantes, mais ce n’est pas obligatoire. j’ai vu

 private static final Logger log = Logger.getLogger(MyClass.class); 

en minuscule avant, et je vais bien car je sais que je ne peux utiliser que le journal pour enregistrer les messages, mais cela ne respecte pas la convention. Vous pouvez prétendre que le nommer log est une sous-convention, je suppose. Mais en général, nommer des constantes en majuscule n’est pas la bonne solution, mais la meilleure.

Ne vivez pas avec fanatisme les conventions que SUN a adoptées, que ressentez-vous pour vous et votre équipe?

Par exemple, voici comment l’éclipse le fait, en enfreignant la convention. Essayez d’append des implements Serializable et eclipse vous demandera de générer cette ligne.

Mise à jour: Il y avait des cas spéciaux qui ont été exclus ne le savais pas. Je refuse cependant de faire ce que vous et votre équipe semble convenir.