Never ever use finalize in Java
À moins de s’avoir parfaitement ce que vous faite et comment ce que vous faites sera utilisé dans le futur…
Parce que lorsque l’on fait du support, en général on ne touche pas trop à du code bien fait / écrit ni fonctionnel (un produit qui fonctionne n’a pas besoin de support), je vois par moment des choses qui peuvent piquer les yeux.
Dernier en date : utilisation de la méthode finalize
de Java.
Rappel
En C++, il y a les destructeurs, donc on pourrait penser que c’est la même chose : pas du tout ! Le destructeur en C++ est responsable de la désallocation de la mémoire utilisée par l’objet.
La méthode finalize
est appelée lorsque le GC passe sur l’instance d’une classe. On peut alors souhaiter effectuer certaines actions à ce moment là mais il faut faire très attention car une simple raison : on ne sait pas quand le GC passe !
Mise en situation de ce qu’il ne faut pas faire
Code
|
|
|
|
|
|
Exécution
Si votre classe B est un singleton géré par un système tiers, alors on pourrait avoir 10000 instances de A avec la même instance de B. Si, par manque de ressources ou parce que le GC veut faire un peu de ménage, le GC supprime au moins une instance de A, alors
“You gonna have a bad time”
Explication
Lors du passage du GC, les méthodes finalize
sont appelées, sur le principe que toute classe est une fille de la classe Object
qui définit cette méthode. Donc si une instance de A est déchargée, elle va mettre à null
la référence à une instance de C dans l’instance de B.
NPE guaranteed
En effet, l’instance de la classe B est toujours utilisé par d’autres instance de la classe A.
Conclusion
Il y a quelques années, un enseignant nous avait dit :
“Le premier que je vois redéfinir
finalize
sans une excellente raison passera un sale quart d’heure”, Rémi FORAX.
Depuis j’applique ce précepte : “Je ne sais pas suffisamment comment ça sera utilisé pour être capable de faire une redéfinition parfaite”, donc je ne redéfinis jamais la méthode finalize
.