Chaque article de la catégorie Pratique met le focus sur une mauvaise pratique de développement détectée par le Cockpit Kalistick.
L’appel d’une méthode interne dérivable (non final en java, ou virtual en C#) depuis le constructeur de sa classe est une pratique risquée : dans le cas où cette méthode est surchargée, des incohérences voire même des erreurs peuvent apparaître.
Les raisons intrinsèques de ces erreurs sont intiment liées au processus d’instanciation des objets dans les langages C# / Java, et notamment à l’exécution des constructeurs parents avant même l’initialisation des champs de la classe fille.
Prenons un exemple :
MyWindow.java
public class MyWindow
{
public MyWindow()
{
/* ... */
buildUI();
}
public void buildUI()
{
/* ... */
}
}
MyExtendedWindow.java
public class MyExtendedWindow extends MyWindow
{
private MyComponent component;
public MyExtendedWindow()
{
this.component = new MyComponent();
}
public void buildUI()
{
super.buildUI();
component.setWidth(800);
}
}
La méthode buildUI de la classe MyWindow est dérivable et appelée dans le constructeur de la classe MyWindow.
La classe MyExtendedWindow étend MyWindow et surcharge la méthode buildUI afin d’ajouter des traitements sur ses champs.
A l’instanciation d’un objet de la classe MyExtendedWindow, l’ordre d’exécution sera le suivant :
- Initialisation des champs de la classe
MyWindow(déclaration) - Exécution du constructeur de la classe
MyWindow - Exécution de la méthode
buildUIde la classeMyExtendedWindow(surcharge) - Initialisation des champs de la classe
MyExtendedWindow(déclaration) - Exécution du constructeur de la classe
MyExtendedWindow
L’instanciation aboutira à une exception de nullité (en 3) car la méthode setWidth de MyComponent est appelée avant l’initialisation de l’objet component qui se fera en 5. Ici, l’erreur est flagrante. Dans d’autres circonstances, les symptômes peuvent être moins évidents et rendre le diagnostic bien plus chronophage !
Les différentes corrections possibles :
- déclarer la méthode
buildUInon dérivable ou privée au niveau deMyWindowafin qu’elle ne puisse plus être surchargée. - sortir la méthode
buildUIdu constructeur deMyWindowet l’appeler explicitement après le constructeur.
No related posts.
