Tout d'abord, l'utilisation de WeakReference dans les listes d'écoute donnera à votre objet différents sémantique puis en utilisant des références dures. Dans le cas d'une référence directe, addListener(...) signifie "notifier l'objet fourni d'un ou de plusieurs événements spécifiques". jusqu'à ce que je l'arrête explicitement avec removeListener(..)", dans le cas d'une référence faible, cela signifie "notifier à l'objet fourni un ou plusieurs événements spécifiques". jusqu'à ce que cet objet ne soit plus utilisé par personne d'autre (ou arrêter explicitement avec removeListener)". Notez qu'il est parfaitement légal, dans de nombreuses situations, d'avoir un objet qui écoute certains événements et qui n'a pas d'autres références qui le maintiennent dans la GC. Le logger peut être un exemple.
Comme vous pouvez le voir, l'utilisation de WeakReference ne résout pas seulement un problème ("Je dois garder à l'esprit de ne pas oublier de supprimer l'écouteur ajouté quelque part"), mais en soulève également un autre -- "Je dois garder à l'esprit que mon écouteur peut cesser d'écouter à tout moment quand il n'y a plus de référence à lui". Vous ne résolvez pas le problème, vous échangez juste un problème contre un autre. Regardez, de quelque manière que ce soit vous êtes obligé de définir clairement, de concevoir et de tracer la durée de vie de votre auditeur, d'une manière ou d'une autre.
Donc, personnellement, je suis d'accord avec la mention que l'utilisation de WeakReference dans les listes d'écoute est plus comme un hack qu'une solution. C'est un modèle qui vaut la peine d'être connu, parfois il peut vous aider -- pour faire fonctionner correctement un code hérité, par exemple. Mais ce n'est pas un pattern de choix :)
P.S. Il faut également noter que WeakReference introduit un niveau supplémentaire d'indirection, qui, dans certains cas avec des taux d'événements extrêmement élevés, peut réduire les performances.
2 votes
@user : weblogs.java.net/blog/enicholas/archive/2006/05/
1 votes
Que vous apporteraient deux méthodes, à part encombrer l'api ? Bien qu'il soit (encore ?) de bon ton de supprimer tous les listeners qui ont été ajoutés si possible, il n'y a généralement pas de mal à ne pas le faire : le garbage collection s'en charge sauf dans de très rares cas. Si vous rencontrez une fuite de mémoire produite par un listener non libéré, analysez soigneusement la situation et faites quelque chose d'analogue à ce que AbstractButton fait avec son PropertyChangeListener d'Action.
1 votes
Si vous avez une écoute référencée faible, vous n'aurez pas besoin d'"analyser soigneusement la situation" ;)
0 votes
J'utilise des listeners faibles mais pas en tant que partie de l'interface, seulement en interne, ce qui impose de garder une référence externe à l'listener ET de le désenregistrer (les classes anon. peuvent ne pas avoir ladite référence). Sinon, il y a une référence conservée qui fuit tout simplement. Il est important de se rappeler que tout addXXXListener doit être suivi par removeXXXListener pour assurer un cycle de vie normal. Le désenregistrement n'est pas une option (sauf si les deux objets ont la même portée de cycle de vie). Ce modèle est à la fois utile pour les alias swing et surtout pour le développement de serveurs.
0 votes
@pdeva, si vous avez une écoute référencée faible, vous n'aurez pas besoin d'"analyser soigneusement la situation" ;) c'est vraiment faux, vraiment faux, si vous avez un listener faible, celui qui est enregistré pour l'événement ne recevra rien puisqu'il n'y aura plus de références supplémentaires et le listener sera GC'd.
1 votes
Beaucoup de réponses ici de la part de personnes qui ne voient pas pourquoi une WeakReference aurait un sens, alors j'ai pensé ajouter au moins une référence à ce que je pense être le problème prototypique qu'elle résout : la problème de l'auditeur défaillant .