[JAVA] Je n'ai pas compris la différence entre Collections.emptyMap et Collections.EMPTY_MAP, et mon collègue s'est mis en colère, alors je vais l'écrire ici pour l'auto-discipline.

Cet article est une réimpression d'un article de blog. https://munchkins-diary.hatenablog.com/entry/2018/11/14/034818

Bonsoir, je suis un développeur Java / Scala qui est devenu un amoureux de la JVM après avoir appris le fonctionnement du compilateur C1C2. (Mon nom n'est pas stable) Aujourd'hui (ou hier), a souligné mon collègue, et pour la première fois j'ai réalisé la différence entre les cartes vides des collections, je vais donc la poster ici avec le sens de la prochaine fois. Cela fait longtemps que j'ai écrit Java pour la première fois, mais c'était une bonne étude car je ne le savais pas du tout même si c'était très rudimentaire.

Premier de la conclusion

Le sujet principal et l'explication qui suit sont longs, donc j'écrirai d'abord à partir de la conclusion. Collections.emptyMap: À moins que le type de ligne ne soit utilisé pour le type de variable ou de valeur de retour, il est converti en type spécifié dans la méthode et est type safe. '' **Collections.EMPTY_MAP:** Puisqu'il s'agit d'un objet canonique de type ligne, il n'y a pas de spécification de type dans les génériques et ce n'est pas type safe. ''

Il est également correctement décrit dans le JavaDoc officiel d'Oracle. https://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#emptyMap%28%29

Contrairement à cette méthode, le champ ne fournit pas de sécurité de type (contrairement à cette méthode, le champ (EMPTY_MAP) n'est pas de type sécurisé.)

(Voir la discussion plus loin sur les raisons pour lesquelles les méthodes et les constantes ont le même objectif.)

Gudaguda et un long sujet et comment il s'est mis en colère

Après le déjeuner, alors que je parcourais l'architecture de microservices d'O'Reili à mon bureau, j'ai reçu un message Slack quelque peu dérangeant d'un collègue étranger travaillant au Japon (appelons-le Linus).

Linus: Mon profil indique Vacances, mais êtes-vous toujours en vacances? Moi: Mon cœur est en vacances sans fin ... (je me couche) Qu'est-ce qui ne va pas? La: Non, ton code est si terrible que tu as envie de pleurer ... Moi: Hé ... La: Ne pensez-vous pas que c'est des ordures quand vous le voyez par vous-même? Moi: Je ne pense pas que ce soit un problème pour Repository ... La: Repository Hey ...

C'est un épéiste au milieu. (En son honneur, il n'utilise ce libellé que techniquement, en particulier pour les erreurs stupides et le code sale, mais c'est généralement le plus doux et le plus humoristique ~~ Geek ~~ Guy)

Pour faire une excuse, je savais qu'il y avait des problèmes parce que c'était la classe que j'écrivais quand je conduisais au trimestre précédent, mais je ne pensais pas que c'était un design aussi terrible. Il est le leader de l'équipe back-end et est assez occupé, alors je lui ai demandé de me donner des commentaires pendant son temps libre et j'ai rompu. Le soir, lorsque le travail s'était quelque peu calmé, il m'a envoyé un autre message.

Linus: Avez-vous remarqué des problèmes dans cette classe?

J'ai soulevé des problèmes de conception autant que je pouvais penser et j'ai attendu sa réaction. Mais ce qui est revenu de lui était une réponse plus simple.

Non, vous savez, faites d'abord les bases avant de dire un si gros problème.

  1. ʻImmutableMap.Builder retvalBuilder = ImmutableMap. <String, T> builder (); `Ceci est un type brut
  2. Connaissez-vous la différence entre return Collections.EMPTY_MAP; et return Collections.emptyMap ();?
  3. return this.getXXXByIds (Arrays.asList (id)). GetOrDefault (id, null); Vous mentionnez NPE dans JavaDoc, mais vous ne gérez pas correctement les valeurs nulles. Pourquoi ne pas retourner facultatif? En premier lieu, getOrDefault (x, null) et get (x) sont identiques.

Quant aux 1 et 3, au moment où je les ai vus, j'ai eu honte de rougir. Je veux entrer s'il y a un trou. Je n'ai pas d'autre choix que d'être honnête. Je vais l'exposer ici avec le sens de la réflexion. Après tout, la chose fondamentale à dire est que j'enseigne moi-même à plusieurs reprises des juniors travaillant dans d'autres pays dans des revues. Cependant, je ne pensais pas du tout que c'était un problème. Après tout, Collections.EMPTY_MAP est canonique et immuable. J'ai pensé qu'il serait préférable d'utiliser un objet canonique (bien que ce soit une erreur) car il est plus convivial pour la mémoire s'il ne change pas de toute façon.

Cependant, lorsque j'ai lu JavaDoc, le sens est devenu clair. C'est écrit correctement, il y a un risque d'utiliser EMPTY_MAP pour la valeur de retour.

Contrairement à cette méthode, le champ ne fournit pas de sécurité de type (contrairement à cette méthode, le champ (EMPTY_MAP) n'est pas de type sécurisé.)

Oui, ce n'est pas de type sécurisé, EMPTY_MAP. Nous, les programmeurs Java, vivons protégés par la puissante fonction de saisie de Java. Les programmeurs qui écrivent du code atypiquement sûr sont aussi immatures que les lycéens de la période rebelle, qui vivent sous la protection de leurs parents et méprisent leurs parents.

(Je suis désolé d'avoir trop dit)

Eh bien, pourquoi y a-t-il deux constantes et méthodes même si ce n'est pas Singlton en premier lieu?

Collections.EMPTY_MAP devrait être une constante inutile selon les normes actuelles, mais j'ai compris la raison en regardant la version publiée.

** Collections.EMPTY_MAP a été publié en Java3 et Collections.emptyMap a été publié en Java5. ** **

Generics est assis avec le visage qu'il existe depuis longtemps maintenant, mais cette fonctionnalité n'a été introduite dans Java que récemment dans Java5. (Quand j'ai commencé Java, je ne pouvais pas spécifier le type, donc je l'ai casté un par un.)

En d'autres termes, Collections.EMPTY_MAP a été créé en tant qu'objet canonique sans spécification de type car il a été créé à l'époque où il n'y avait pas de génériques, mais depuis que les génériques ont été levés dans Java 5, une méthode Collections.emptyMap plus sûre de type a été créée. Je dirais que. Bien sûr, la bibliothèque standard doit être rétrocompatible, de sorte que Collections.EMPTY_MAP tourne toujours autour du terrain avec énergie.

…… Mais honnêtement, je me demande si cela peut être utilisé. Le fait qu'il ne soit pas spécifié comme obsolète a probablement une utilisation prévue, mais je ne sais personnellement pas comment l'utiliser correctement dans Java aujourd'hui. Si quelqu'un sait, faites-le moi savoir dans les commentaires.

Résumé

La constante EMPTY_MAP de la classe Collections n'est pas de type sécurisé et la méthode emptyMap est de type sécurisé. Donc, fondamentalement, pour Java 5 et au-dessus, il est plus sûr de créer une carte vide avec la méthode emptyMap.

C'est une petite chose, mais Linus et moi avons le plus grand respect pour Java et les JVM (et tous les langages, infrastructures et développeurs de systèmes d'exploitation), donc ces petites erreurs devraient être assez énervantes. Je reconnais cela. Cela fait un bon bout de temps que j'ai commencé à écrire Java, mais il y a encore beaucoup de choses que je ne sais pas, et je pense que c'est un langage vraiment enrichissant à étudier.

D'ailleurs, en ce qui concerne l'architecture de micro-service mentionnée au début, j'écrirai un autre article sur mon blog et Qiita, donc je le publierai plus tard.

C'est un résumé qui n'a rien à voir avec le sujet principal, eh bien. Puis!

Recommended Posts

Je n'ai pas compris la différence entre Collections.emptyMap et Collections.EMPTY_MAP, et mon collègue s'est mis en colère, alors je vais l'écrire ici pour l'auto-discipline.
Je ne comprends pas la méthode devise_parameter_sanitizer, je vais donc l'afficher ici.
[iOS] Comprendre la différence entre le cadre et les limites
Comprenez la différence entre les classes abstraites et les interfaces!
Je ne comprenais pas le tri topologique, alors je l'ai recherché et mis en œuvre dans BFS, puis j'ai essayé de résoudre le problème d'AtCoder.
[Rails] J'ai étudié la différence entre les ressources et les ressources