S'appuyer sur l'initialisation du champ par défaut - est-ce un mauvais style de programmation? [fermé]

20

J'ai reçu un lien vers la documentation officielle d'Oracle: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

où il est dit:

Les valeurs par défaut

Il n'est pas toujours nécessaire d'attribuer une valeur lorsqu'un champ est déclaré. Les champs déclarés mais non initialisés seront définis par défaut par le compilateur. De manière générale, cette valeur par défaut sera zéro ou nulle, selon le type de données. S'appuyer sur de telles valeurs par défaut, cependant, est généralement considéré comme un mauvais style de programmation.

Je veux souligner cette partie:

S'appuyer sur de telles valeurs par défaut, cependant, est généralement considéré comme un mauvais style de programmation.

Mais, oh boy, c'est, je dirais, une partie fondamentale de la spécification du langage sachant que les variables d'instance ont des valeurs par défaut. Pourquoi diable c'est une mauvaise pratique de programmation si elle est largement utilisée même dans le code source des bibliothèques Java SE?

Andremoniy
la source
5
Huh. Je n'ai jamais su que cette déclaration était là. Je considère en fait que c'est une bonne pratique de compter sur eux. private int count = 0;est un code qui ne fait rien, et un code qui ne fait rien est un fouillis. C'est comme importer des classes depuis java.lang, ou déclarer une classe avec extends Object.
VGR
2
... ou ayant une public abstractméthode dans une interface.
mumpitz
1
quel est le problème avec le résumé public?
John Keates
1
Une pièce du puzzle peut provenir de C ++. C'est un langage populaire, et sa gestion de l'initialisation par défaut par rapport à l'initialisation zéro est une source continue de bogues. En C ++, c'est une mauvaise idée de s'appuyer sur les valeurs par défaut dans tous les cas sauf les plus exceptionnels. Cela peut avoir fui culturellement à Java.
Cort Ammon
@JohnKeates - Mon Java est un peu rouillé, mais les privateméthodes dans une interface n'auraient aucun sens et abstractsont implicites.
Scott Smith

Réponses:

6

Le texte cité est:

"Cependant, se fier à de telles valeurs par défaut est généralement considéré comme un mauvais style de programmation."

Cyniquement: "il est généralement considéré que" est souvent une façon de dire que l'auteur n'a pas essayé de trouver une source faisant autorité pour la déclaration présentée.

Dans ce cas, l'affirmation est clairement discutable. Preuve: 5 guides de style Java sur 5 échantillonnés ne disent PAS si vous devez ou devez vous fier aux valeurs par défaut:

(Remarque, ma méthodologie d'échantillonnage consistait à examiner les 5 premiers résultats de recherche Google distincts pour "guide de style java". Ensuite, j'ai cherché chaque document pour "par défaut". Ce n'est pas une analyse approfondie, mais cela sert à faire valoir mon point de vue. )


D'ACCORD. Cela facilite-t-il vraiment la lisibilité du code Java?

C'est discutable.

D'une part, un programmeur Java novice qui n'a pas appris l'initialisation par défaut peut être dérouté quant à la provenance des zéros ou des null. Mais s'ils prennent la peine de chercher une initialisation explicite et en trouvent qu'il n'y en a pas, cela devrait être suffisant pour leur faire lire un tutoriel ou un livre pour en savoir plus sur l'initialisation par défaut. (Vous espérez!)

D'un autre côté, nous ne nous attendons pas normalement à ce que les programmeurs Java novices maintiennent des bases de code de production. Pour un programmeur Java expérimenté, une initialisation redondante n'améliore pas la lisibilité. C'est (au mieux) du bruit.

À mon avis, la seule chose qui est réalisée par une initialisation redondante d'un champ est de signaler à un futur lecteur de votre code que vous avez pensé à la valeur initiale. (Comme @GhostCat l'a exprimé, l'initialisation par défaut ne communique pas l'intention.)

Mais inversement, si j'étais ce lecteur, je ne ferais pas nécessairement confiance à la pensée de l'auteur du code. La valeur de ce "signal" est donc également discutable.


Et la fiabilité?

En Java, cela ne fait aucune différence. Le JLS spécifie que l' initialisation par défaut ne se produit pour les champs. Et inversement, pour les variables locales, c'est une erreur de compilation que d'essayer d'utiliser une variable qui n'a pas été définitivement initialisée.

En bref, le comportement à l'exécution d'une variable qui n'est pas explicitement initialisée est entièrement prévisible.

En revanche, dans des langages comme C ou C ++ où les variables peuvent ne pas être initialisées, le comportement n'est pas spécifié et peut entraîner des plantages et des différences de comportement sur différentes plates-formes. Le cas d'une initialisation toujours explicite des variables est beaucoup plus fort ici.


Et la performance?

Cela ne devrait faire aucune différence. Le compilateur JIT doit pouvoir traiter une initialisation redondante et une initialisation par défaut comme identiques.

Stephen C
la source
19

Simple: s'appuyer sur des valeurs par défaut ne communique pas l'intention.

Vouliez-vous vraiment que ce champ commence par 0, ou avez-vous oublié d'attribuer une valeur?!

Et bien sûr, une référence null est la moitié des deux choses dont vous avez besoin pour exécuter une exception nullpointer.

Enfin, l'utilisation des valeurs par défaut implique que vous avez des champs non finaux. Que vous évitez autant que possible.

Le seul contre-argument est: pourquoi écrire des choses que vous n'avez pas à faire? Mais je pense que les inconvénients énumérés trompent cela, attribuer ainsi 0 à un champ explicitement est mieux que de le laisser au compilateur.

GhostCat salue Monica C.
la source
3
ie re: not communicating intention - Et si "Manny le mainteneur" regarde votre code et ne sait pas quelle est la valeur par défaut pour un type de données spécifique. Il suppose que c'est 0 quand c'est vraiment NULL et c'est le bogue entier sur un contrôle === (ou quoi que le contrôle d'égalité équivalent pour la valeur et le type soit en java, equals ()?). Des heures de recherche (pour un programmeur inexpérimenté) pourraient être le résultat de quelque chose de si simple. PS essayant de jouer l'avocat du diable. Je dis utiliser les valeurs par défaut toute la journée (même si je ne le fais jamais) et obtenir des gens plus intelligents (ou au moins une plus grande attention aux détails) pour maintenir votre code.
TCooper du
@TCooper quand mannie le mainteneur en sait si peu sur Java, alors il n'a rien à faire avec le code Java du monde réel. Mais je suis d'accord avec la notion sous-jacente. Cela rend les choses plus difficiles pour les débutants.
GhostCat salue Monica C.
12

Pourquoi diable c'est une mauvaise pratique de programmation

L'idée est que si vous vous fiez à une valeur par défaut, il n'est pas immédiatement clair pour quiconque lit le code si vous l'avez délibérément laissé comme valeur par défaut, ou si vous avez simplement oublié de l'assigner.

... s'il est largement utilisé même dans le code source des bibliothèques Java SE ??

Le code source Java n'est pas vraiment quelque chose sur lequel vous devriez vous fier comme exemple de pratique de codage exemplaire. Il existe de nombreux cas où de telles règles sont violées (parfois intentionnellement pour des améliorations mineures des performances, et parfois accidentellement ou parce que le style accepté a changé au fil des ans.)

Michael Berry
la source
2
C'est probablement vrai, bien que je ne sois pas d'accord avec cela.
VGR
3
@VGR Même si j'ai tendance à être d'accord avec l'affirmation selon laquelle s'appuyer sur des valeurs par défaut est sous-optimal, j'ai pris soin de le formuler de manière neutre pour cette raison. La qualité du code est subjective, et je suis bien conscient qu'il ne s'agit en aucun cas d'un point de vue universel.
Michael Berry