54 votes

Modificateur final Java

On m'a dit que j'ai mal compris les effets de l' final. Quels sont les effets de l' final mot-clé?

Voici bref aperçu de ce que je pense, je sais:

Java final modificateur (aka l'agrégation de lien)

primitive variables: peut être définie qu'une seule fois. (de mémoire et de performances le gain)
les objets variables: peut être modifié, final s'applique à l'objet de référence.
champs: peut être définie qu'une seule fois.
méthodes: ne peut pas être remplacé, caché.
classes: ne peut pas être prolongé.
la collecte des ordures: force Java générations de collecte des ordures mark-sweep à double balayage.

Pouvez et ne peux

  • Peut cloner un échec (c'est à la fois bon et mauvais)
  • Peut rendre immuable primitives aka const
  • Peut faire vide immuable - initialisé lors de la création aka readonly
  • Peut rendre les objets faiblement immuable
  • Peut faire de la portée et de la visibilité immuable
  • Peut faire appel de méthode généraux les plus petits (parce qu'il n'a pas besoin de table virtuelle)
  • Peut faire des arguments de méthode utilisé comme final (même si ton ne le sont pas)
  • Peut rendre les objets thread-safe (si l'objet est défini comme une finale, il l'habitude de faire des arguments de méthode finale)
  • Peut se moquer de faire des tests (non pas que vous pourriez faire quelque chose à ce sujet - vous pouvez dire les bugs sont destinés)
  • Ne peut pas se faire des amis (mutable avec d'autres amis et immuable pour le reste)
  • Ne pouvez pas faire mutable qui est changé pour être immuables plus tard (mais avec de l'usine modèle de type fix)
  • Ne pouvez pas faire les éléments du tableau immuable aka profondément immuable
  • Ne peut pas faire de nouvelles instances de l'objet (c'est à la fois bon et mauvais)
  • Ne peut pas faire de la sérialisation de travail

Il n'existe pas de solutions de rechange à l' final, mais il n'y a wrapper + privé et les énumérations.

74voto

Stephen C Points 255558

Répondant à chacune de vos points tour à tour:

primitive variables: peut être définie qu'une seule fois. (mémoire et de gain de performance)

Oui, mais pas de la mémoire de gain, et pas de gain de performance. (De votre soi-disant gain de performance par la mise qu'une seule fois ... pas de final.)

les objets variables: peut être modifié, final s'applique à l'objet de référence.

Oui. (Cependant, cette description de manquer le point que c'est tout à fait compatible avec la façon dont le reste de la langue de Java traite de l'objet / référence de la dualité. Par exemple, lorsque les objets sont passés en paramètres et de les retourner comme des résultats.)

champs: peut être définie qu'une seule fois.

La vraie réponse est: la même que pour les variables.

méthodes: ne peut pas être remplacé, caché.

Oui. Mais notez aussi que ce qui se passe ici est que l' final mot-clé est utilisé dans un autre contexte syntaxique pour signifier quelque chose de différent à l' final pour un champ variable.

classes: ne peut pas être prolongé.

Oui. Mais également voir la note ci-dessus.

la collecte des ordures: force Java générations de collecte des ordures mark-sweep à double balayage.

C'est de la foutaise. L' final mot-clé n'a aucune importance que ce soit à la collecte des déchets. Vous avez peut être source de confusion final avec la finalisation ... ils ne sont pas liés.

Mais même les finaliseurs ne pas forcer un supplément de balayage. Ce qui se passe est qu'un objet qui doit être finalisé sur un côté jusqu'à ce que le principal GC finitions. La GC, puis exécute la méthode finalize sur l'objet et définit son drapeau ... et continue. La prochaine fois que le GC s'exécute, l'objet est traité comme un objet normal:

  • si elle est accessible, elle est marquée et copié
  • si elle n'est pas accessible, il n'est pas marqué.

(Votre caractérisation - "Java générations de collecte des ordures mark-sweep" est déformé. Un garbage collector peut être soit "mark-sweep" OU "générations" (une sous-classe de "la copie"). Il ne peut pas être les deux. Java utilise normalement intergénérationnel de la collection, et seulement revient à mark-sweep dans les situations d'urgence; c'est à dire lors de l'exécution d'espace ou lorsqu'un faible pause collecteur ne peut pas suivre.)

Peut cloner un échec (c'est à la fois bon et mauvais)

Je ne le pense pas.

Peut rendre immuable primitives aka const

Oui.

Peut faire vide immuable - initialisé lors de la création aka readonly

Oui ... mais je n'ai jamais entendu le terme "vide immuable" utilisé avant.

Peut rendre les objets faiblement immuable

Objet de la mutabilité est de savoir si observables état peut changer. En tant que tel, de déclarer les attributs final peut ou ne peut pas faire l'objet se comporter comme immuable. En plus de la notion de "faiblement immuable" n'est pas bien défini, pas moins parce que la notion de ce qu'est "superficielle" est ne peut pas être mappé sans connaissance profonde de la classe sémantique.

(Pour être clair, la mutabilité des variables, des champs est un concept défini dans le contexte de la JLS. C'est juste le concept de la mutabilité des objets qui n'est pas défini du point de vue de la JLS.)

Peut faire de la portée et de la visibilité immuable

Erreur de terminologie. La mutabilité est à propos de l'état de l'objet. La visibilité et la portée ne sont pas.

Peut faire appel de méthode généraux les plus petits (parce qu'il n'a pas besoin de table virtuelle)

Dans la pratique, ce n'est pas pertinent. Moderne compilateur JIT n'cette optimisation pour les non-finale méthodes, si elles ne sont pas remplacées par une classe que l'application utilise. (Clever choses qui se passe ...)

Peut faire des arguments de méthode utilisé comme final (même si ton ne le sont pas)

Hein? Je ne peut pas analyser cette phrase.

Peut rendre les objets thread-safe

Dans certaines situations, oui.

(si l'objet est défini comme une finale, il l'habitude de faire des arguments de méthode finale)

Oui, si tu veux savoir si la classe est définitive. Les objets ne sont pas définitifs.

Peut se moquer de faire des tests (non pas que vous pourriez faire quelque chose à ce sujet - vous pouvez dire les bugs sont destinés)

Ne pas analyser.

Ne peut pas se faire des amis (mutable avec d'autres amis et immuable pour le reste)

Java n'a pas "d'amis".

Ne pouvez pas faire mutable qui est changé pour être immuables plus tard (mais avec de l'usine modèle de type fix)

Oui pour le premier, un final champ ne peut pas être changé à partir de mutables à immuables.

Il est difficile de savoir ce que tu veux dire par la deuxième partie. Il est vrai que vous pouvez utiliser une usine (ou le constructeur) modèle pour construire des objets immuables. Toutefois, si vous utilisez final pour les champs d'objet, à aucun point de l'objet mutable.

Sinon, vous pouvez implémenter des objets immuables que l'utilisation non-final champs pour représenter l'état immuable, et vous pouvez concevoir l'API de sorte que vous pouvez "appuyer sur un bouton" faire un auparavant mutable objet immuable dès maintenant. Mais si vous prenez cette approche, vous avez besoin d'être beaucoup plus prudent avec la synchronisation ... si vos objets doivent être thread-safe.

Ne pouvez pas faire les éléments du tableau immuable aka profondément immuable

Oui, mais votre terminologie est brisée; voir le commentaire ci-dessus à propos de "superficielle de la mutabilité".

Ne peut pas faire de nouvelles instances de l'objet (c'est à la fois bon et mauvais)

Pas de. Il n'y a rien qui vous empêche de faire une nouvelle instance d'un objet avec la finale de champs ou d'une classe finale ou finale méthodes.

Ne peut pas faire de la sérialisation de travail

Pas de. La sérialisation des œuvres. (Certes, la désérialisation d' final champs à l'aide d'une coutume readObject méthode présente des problèmes ... si vous pouvez travailler autour d'eux en utilisant la réflexion des hacks.)

Il n'existe pas de solutions de rechange à la finale,

Correct.

mais il y a wrapper + privé

Oui, c'est que (à proprement parler) une désynchronisation de lecture pour un non définitif champ peut être non thread-safe ... même si il est initialisé lors de la construction d'objets, puis n'a jamais changé!

et les énumérations.

Résout un problème différent. Et enums peut être mutable.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X