Maison  >  Article  >  Java  >  Explication détaillée de la liaison statique Java et de l'exemple de code de liaison dynamique

Explication détaillée de la liaison statique Java et de l'exemple de code de liaison dynamique

伊谢尔伦
伊谢尔伦original
2017-07-17 16:11:071623parcourir

Liaison statique Java et liaison dynamique

Le concept de liaison de programme :

La liaison fait référence à ce qui est appelé est que l’appel d’une méthode est associé à la classe (corps de la méthode) dans laquelle se trouve la méthode. Pour Java, la liaison est divisée en liaison statique et liaison dynamique ; ou liaison précoce et liaison tardive

Liaison statique :

La méthode a déjà été liée. le programme est exécuté (c'est-à-dire qu'on sait déjà dans quelle classe la méthode est une méthode pendant le processus de compilation), qui est implémenté par le compilateur ou un autre éditeur de liens. Par exemple : C.

Pour Java, cela peut être simplement compris comme une liaison lors de la compilation du programme ; voici une note spéciale, seules les méthodes finales, statiques, privées et constructeur en Java sont pré-liées

Liaison dynamique :

Liaison tardive : liaison basée sur le type de l'objet spécifique au moment de l'exécution.

Si un langage implémente une liaison tardive, il doit également fournir un mécanisme pour déterminer le type de l'objet pendant l'exécution et appeler respectivement les méthodes appropriées. En d'autres termes, le compilateur ne connaît toujours pas le type de l'objet pour le moment, mais le mécanisme d'appel de méthode peut enquêter par lui-même et trouver le corps de méthode correct. Différentes langues implémentent la liaison tardive de différentes manières. Mais nous pouvons au moins penser de cette façon : ils doivent tous placer un type particulier d’informations dans l’objet.

Le processus de liaison dynamique :

  1. La machine virtuelle extrait la table de méthodes du type réel de l'objet ;

  2. La machine virtuelle recherche la signature de la méthode

  3. Appelle la méthode.

À propos de la compréhension que les méthodes finales, statiques, privées et constructeur sont pré-liées

Pour les méthodes privées, tout d'abord, elles ne peuvent pas être héritées. Puisqu'il ne peut pas s'il est hérité, il ne peut pas être appelé via l'objet de sa sous-classe, mais ne peut être appelé que via l'objet de la classe elle-même. On peut donc dire que la méthode privée est liée à la classe qui définit cette méthode.

Bien que la méthode finale puisse être héritée, elle ne peut pas être remplacée (couverte). Bien que l'objet de sous-classe puisse être appelé, la méthode finale définie dans la classe parent est appelée (ainsi nous pouvons le savoir. la méthode est déclarée comme type final, d'une part pour empêcher la méthode d'être remplacée, et d'autre part pour désactiver efficacement la liaison dynamique en Java).
Les constructeurs ne peuvent pas être hérités (on dit aussi sur Internet que les sous-classes héritent inconditionnellement du constructeur sans paramètre de la classe parent en tant que son propre constructeur, mais je pense personnellement que cette affirmation n'est pas appropriée, car nous savons que les sous-classes passent super( ) pour appeler le constructeur sans paramètre de la classe parent pour terminer l'initialisation de la classe parent, nous n'avons pas besoin de le faire lorsque nous utilisons des méthodes héritées de la classe parent, il ne faut donc pas dire que la sous-classe hérite du constructeur de la classe parent). vous pouvez également savoir à quelle classe appartient cette méthode de construction lors de la compilation.

Quant à la méthode statique, je ne peux pas expliquer clairement le principe spécifique. Cependant, sur la base des informations sur Internet et de mes propres expériences, je peux conclure que les méthodes statiques peuvent être héritées par les sous-classes, mais elles ne peuvent pas être remplacées (remplacées) par les sous-classes, mais elles peuvent être masquées par les sous-classes. (Cela signifie que s'il existe une méthode statique dans la classe parent et qu'il n'y a pas de méthode correspondante dans sa sous-classe, alors lorsque l'objet de la sous-classe appelle cette méthode, la méthode de la classe parent sera utilisée. Et si elle est définie dans le sous-classe La même méthode appellera la méthode définie dans la sous-classe. La seule différence est que lorsque l'objet de la sous-classe est transformé en objet de classe parent, l'objet utilisera la méthode statique dans la classe parent, qu'il soit défini ou non dans la sous-classe. .Par conséquent, on dit que les méthodes statiques peuvent être masquées mais pas remplacées. C'est la même chose que la sous-classe masquant les variables membres dans la classe parent. La différence entre le masquage et le remplacement est qu'après la conversion de l'objet de la sous-classe. l'objet de classe parent, il peut être masqué. Accédez aux variables et méthodes cachées de la classe parent, mais ne peut pas accéder aux méthodes remplacées de la classe parent)

De ce qui précède, nous pouvons conclure que si un La méthode ne peut pas être héritée ou ne peut pas être remplacée après l'héritage. Cette méthode utilise alors une liaison statique.

Compilation et fonctionnement de Java

Le processus de compilation de Java consiste à compiler les fichiers source Java en processus de bytecode (code exécutable jvm, c'est-à-dire fichier .class) , pendant lequel Java ne gère pas la mémoire. Au cours de ce processus, le compilateur effectuera une analyse syntaxique et une erreur sera signalée si la syntaxe est incorrecte.

Le processus en cours d'exécution de Java fait référence à la jvm (machine virtuelle Java) qui charge le fichier de bytecode et l'interprète pour l'exécution. Au cours de ce processus, la disposition de la mémoire est réellement créée et le programme Java est exécuté.
Il existe deux manières d'exécuter le bytecode Java : (1) Méthode de compilation juste à temps : l'interpréteur compile d'abord les octets en code machine, puis exécute le code machine (2) Méthode d'exécution par interprétation : l'interpréteur passe ; chacun Interprète et exécute un petit morceau de code à la fois pour terminer toutes les opérations du programme de bytecode Java. (Nous pouvons voir ici que le programme Java est en fait converti deux fois lors de l'exécution, d'abord en bytecode puis en code machine. C'est pourquoi Java peut être compilé une fois et exécuté partout. Sur différentes plateformes En installant la machine virtuelle Java correspondante, le même le bytecode peut être converti en code machine sur différentes plateformes, afin de s'exécuter sur différentes plateformes)

Comme mentionné précédemment, pour les méthodes en java, à l'exception des méthodes finales, statiques, privées et constructeur qui sont pré-liées , toutes les autres méthodes sont liées dynamiquement.
La liaison dynamique se produit généralement sous la déclaration de conversion de la classe et de la sous-classe parent :

Par exemple : Parent p = new Children();

Les détails spécifiques du processus sont les suivants :

1 : Le compilateur vérifie le type déclaré et le nom de méthode de l'objet.

Supposons que nous appelions la méthode x.f(args) et que x ait été déclaré comme objet de classe C, alors le compilateur énumérera toutes les méthodes nommées f dans la classe C et toutes les méthodes de la classe C. méthode f héritée de la super classe.

2 : Ensuite, le compilateur vérifie les types de paramètres fournis dans l'appel de méthode.

Si parmi toutes les méthodes nommées f, il existe un type de paramètre qui correspond le mieux au type de paramètre fourni par l'appel, alors cette méthode est appelée. Ce processus est appelé "résolution de surcharge".

3 : Lorsque le programme est en cours d'exécution et qu'une méthode est appelée à l'aide d'une liaison dynamique, la machine virtuelle doit appeler une version de la méthode qui correspond au type réel de l'objet pointé par x.

Supposons que le type réel soit D (une sous-classe de C). Si la classe D définit f(String), alors cette méthode est appelée. Sinon, la méthode f(String) est recherchée dans. la superclasse de D. , et ainsi de suite.
Lorsque la machine virtuelle JAVA appelle une méthode de classe (méthode statique), elle sélectionnera la méthode à appeler en fonction du type de référence d'objet (généralement connue au moment de la compilation). Au contraire, lorsque la machine virtuelle appelle une méthode d'instance, elle choisira la méthode à appeler en fonction du type réel de l'objet (qui ne peut être connu qu'au moment de l'exécution). Il s'agit d'une liaison dynamique, qui est un type de polymorphisme. . La liaison dynamique offre une grande flexibilité pour résoudre des problèmes commerciaux réels et constitue un très beau mécanisme.

Contrairement aux méthodes, lorsqu'il s'agit de variables membres (variables d'instance et variables de classe) dans les classes Java, la liaison d'exécution n'est pas utilisée, mais la liaison statique au sens général. Par conséquent, dans le cas d'une transformation ascendante, la méthode de l'objet peut trouver la sous-classe, mais les attributs de l'objet (variables membres) sont toujours les attributs de la classe parent (la sous-classe masque les variables membres de la classe parent).


public class Father { 
  protected String name = "父亲属性"; 
}   
public class Son extends Father { 
  protected String name = "儿子属性"; 
  
  public static void main(String[] args) { 
    Father sample = new Son(); 
    System.out.println("调用的属性:" + sample.name); 
  } 
}

Conclusion, le membre appelé est l'attribut du père.

Ce résultat montre que l'objet de la sous-classe (handle de référence de la classe parent) appelle la variable membre de la classe parent. Il doit donc être clair que la portée de la liaison d'exécution (dynamique) est uniquement la méthode de l'objet.

Vous essayez maintenant d'appeler le nom de la variable membre de la sous-classe. Que devez-vous faire ? Le moyen le plus simple consiste à encapsuler la variable membre dans une méthode getter.
Le code est le suivant :


public class Father { 
  protected String name = "父亲属性"; 
  public String getName() { 
    return name; 
  } 
}   
public class Son extends Father { 
  protected String name = "儿子属性"; 
  public String getName() { 
    return name; 
  } 
  public static void main(String[] args) { 
    Father sample = new Son(); 
    System.out.println("调用的属性:" + sample.getName()); 
  } 
}

Résultat : L'attribut du fils s'appelle

Pourquoi Java adopte-t-il une méthode de liaison statique pour les propriétés ? En effet, la liaison statique présente de nombreux avantages. Elle nous permet de rechercher les erreurs dans le programme au moment de la compilation plutôt qu'au moment de l'exécution. Cela améliorera l’efficacité de fonctionnement du programme !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn