ProgrammationDéveloppeur Java

Comment fonctionne le mécanisme de liaison dynamique (dynamic binding) en Java, et quelle est la différence entre la liaison statique et la liaison dynamique des méthodes ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

En Java, le mécanisme de liaison dynamique (dynamic binding) détermine quelle méthode sera appelée au moment de l'exécution (runtime), et non au moment de la compilation. La principale différence par rapport à la liaison statique (static binding) est que les méthodes privées, statiques, finales et les méthodes non redéfinies sont liées de manière statique (la liaison se fait au moment de la compilation), tandis que les méthodes d'instance ordinaires (y compris celles qui sont redéfinies) sont liées de manière dynamique. Cela rend le polymorphisme possible.

Exemple :

class Animal { void makeSound() { System.out.println("Un son"); } } class Dog extends Animal { void makeSound() { System.out.println("Aboyer"); } } public class Test { public static void main(String[] args) { Animal a = new Dog(); a.makeSound(); // Affichera : Aboyer (liaison dynamique) } }

Ici, la méthode makeSound() est liée dynamiquement – la JVM détermine quelle variante appeler uniquement au moment de l'exécution.

Question piège

Question : "Si l'on déclare une variable de type interface ou classe abstraite et lui assigne une instance de classe dérivée, quelle méthode sera appelée lors de l'appel à la méthode redéfinie ? Comment le compilateur le détermine-t-il ?"

Erreur fréquente : Beaucoup pensent que cela appelle la méthode en fonction du type de la référence au moment de la compilation, mais cela est fait par la JVM au moment de l'exécution.

Réponse correcte : La JVM utilise le type de l'objet réel pour appeler la méthode (liaison dynamique), et non le type de la référence.

Shape s = new Circle(); s.draw(); // la méthode draw() de Circle sera appelée, et non celle de Shape

Exemples d'erreurs réelles dues à un manque de compréhension des subtilités du sujet


Histoire

Dans un grand projet bancaire, un développeur a redéfini les méthodes toString() et equals(), pensant que si on déclarait une variable via une interface, la méthode serait appelée selon l'interface. En conséquence, la comparaison des objets était incorrecte — des références étaient comparées, et non des valeurs, ce qui a conduit à une logique de comparaison erronée des clients lors de la recherche de doublons.


Histoire

Dans un projet de e-commerce, un développeur a créé une classe de base Product et un héritier ElectronicProduct. Un tableau Product[] a conservé des objets des deux types. Lors de l'affichage d'un produit via la méthode redéfinie dans ElectronicProduct, seule l'information de la classe de base était affichée, car la méthode statique a été appelée ! L'erreur a été remarquée avant la publication.


Histoire

Dans un projet de modélisation de transport, le modèle Factory a été utilisé. Le développeur n'a pas remarqué qu'il travaillait avec des champs et non avec des méthodes : l'accès à un champ de la classe dérivée renvoyait la valeur de la classe de base, et non celle redéfinie, car les champs ne sont pas polymorphes ! Le système calculait incorrectement les itinéraires, affichant à tous les objets le type "Transport".