La liaison fait référence à l'association d'un appel de méthode à la classe dans laquelle il se trouve.
La liaison peut être divisée en liaison statique et liaison dynamique.
Quelques concepts à connaître avant d'analyser la liaison statique et la liaison dynamique :
Période de compilation : Le processus de compilation consiste à convertir la source Java Le processus de compilation d'un fichier en bytecode (fichier .class, code exécutable JVM). Au cours de ce processus, Java ne gère pas la mémoire. Au cours de ce processus, le compilateur effectuera une analyse syntaxique. Si la syntaxe est incorrecte, une erreur sera générée. rapporté.
Période d'exécution : Le processus en cours d'exécution signifie que la JVM (machine virtuelle Java) charge le fichier de bytecode et l'interprète pour l'exécution. Ce processus est la véritable création de. mémoire. Exécutez le programme Java.
Le processus d'appel de méthode en Java est le suivant :
Éditeur Afficher le type déclaré et les noms de méthode de l'objet. Obtenez toutes les méthodes candidates qui peuvent être appelées en raison d’une surcharge de méthode. Par exemple : la première méthode est print(String str), la deuxième méthode est print(int).
Le compilateur examine les types de paramètres d'entrée de la méthode appelante. Choisissez la méthode de correspondance parmi les méthodes candidates. Par exemple, si le paramètre d'entrée est "hello", sélectionnez print(String str).
Si la méthode est privée, statique, finale ou constructeur, le compilateur peut déterminer quelle méthode appeler. Il s'agit d'une liaison statique.
Si ce n'est pas le cas, une liaison d'exécution (dynamique) doit être utilisée.
Liaison statique, également connue sous le nom de liaison anticipée et de liaison au moment de la compilation. Indique la liaison au moment de la compilation, c'est-à-dire que la méthode a été liée avant l'exécution du programme.
Seules les méthodes, variables membres et constructeurs modifiés par final, static et private sont liés statiquement :
类型 | 解释 |
---|---|
final | 被其修饰的方法可以被继承,但不能被重写;子类对象可以调用,但是调用的是父类中定义的那个方法;间接表明将方法声明为 final 可以避免重写,关闭动态绑定。 |
private | 被其修饰地方法隐式地包含了 final 关键字。由于它对外是不可见的,所以不能被继承,重写;只能通过类自身的对象来调用,因此在方法运行之前就可以明确对象。 |
static | 静态方法是依赖于类而依赖于对象的。它可以被子类继承(实质是被子类隐藏),但是不能被子类重写。当子类对象向上转型为父类对象时,不论子类中有没有定义这个静态方法,该对象都会使用父类中的静态方法。因此这里说静态方法可以被隐藏。 |
成员变量 | 默认 Java 对属性采用静态绑定,这样在编译期就能发现程序错误,能够提供效率。 |
构造方法 | 构造方法不能被继承的,子类继承父类时默认要先调用父类的构造方法(无论显示或隐式)。因此在程序运行之前就可以知道构造方法术语哪个对象。 |
Regardez l'exemple suivant :
// 父类class Parent{ // 变量 String name="Parent"; // 静态方法 static void print(){ System.out.println("Parent print"); } // 私有方法 private void say(){ System.out.println("Parent say"); } // 终态方法 final void look(){ System.out.println("Parent look"); } }// 子类class Son extends Parent{ String name ="Son"; static void print(){ System.out.println("Son print"); } // 编译错误,无法重写父类的 final方法 final void look(){}; }public class Test{ public static void main(String[] args) { // 发生向上转型 Parent p = new Son(); // 输出 Parent System.out.println(p.name); // 输出 Parent print p.print(); // 编译错误,对外不可见 p.say(); } }
La liaison dynamique, également connue sous le nom de liaison tardive et de liaison d'exécution, signifie une liaison en fonction du type d'objet spécifique au moment de l'exécution.
Processus de liaison dynamique :
La machine virtuelle extrait la table de méthodes du type réel de l'objet
Virtuel ; recherche automatique Signature de la méthode
appelle la méthode.
Regardons un exemple :
class A { int x = 5; } class B extends A { int x = 6; } class Parent { public A getValue() { System.out.print("Parent Method "); return new A(); } } class Son extends Parent { public B getValue() { System.out.print("Son Method "); return new B(); } }public class Test { public static void main(String[] args) { // 向上转型 Parent p = new Son(); // 输出结果:Son Method 5 // 注意:是 5 不是 6 ! System.out.println(p.getValue().x); } }
Observons l'analyse de sortie comme suit :
p.getValue( ), Puisque la transformation vers le haut s'est produite, il recherche d'abord la méthode de la sous-classe (Son), et à ce moment il appelle la méthode de Son. Il s'agit d'une liaison dynamique.
p.getValue().x. Puisque x est une variable membre, son objet (appartenant au Parent) est déterminé avant l'exécution du programme.
Si vous ne comprenez toujours pas, regardons un autre exemple :
class Parent { String name = "Parent " + this.getClass().getName(); } class Son extends Parent { String name = "Son" + this.getClass().getName(); }public class Test { public static void main(String[] args) { // 向上转型 Parent p = new Son(); // 输出:Parent Son System.out.println(p.name); } }
Observez l'analyse de sortie comme suit :
p .name : name est une variable membre, la liaison statique se produit à ce moment-là, donc la propriété Parent est appelée.
this.getClass( ) : getClass est une méthode. Puisque la transformation vers le haut se produit à ce moment-là, le programme par défaut recherchera cette méthode à partir de la sous-classe, qui existe également dans la sous-classe. Par conséquent, la méthode de la sous-classe est appelée et une liaison dynamique se produit à ce moment-là.
Ce qui précède est le contenu de 07.Java Basics - Static Binding & Dynamic Binding Pour plus de contenu connexe, veuillez faire attention au PHP chinois. site Web (www.php.cn) !