# java 中的静态和动态绑定

> 原文： [https://beginnersbook.com/2013/04/java-static-dynamic-binding/](https://beginnersbook.com/2013/04/java-static-dynamic-binding/)

方法调用与方法体的关联称为绑定。有两种类型的绑定：**静态绑定**在编译时发生，**动态绑定**在运行时发生。在我解释 java 中的静态和动态绑定之前，让我们看一些可以帮助您更好地理解这个概念的术语。

## 什么是参考和对象？

```java
class Human{
....
}
class Boy extends Human{
   public static void main( String args[]) {
       /*This statement simply creates an object of class
        *Boy and assigns a reference of Boy to it*/  
       Boy obj1 = new Boy();

       /* Since Boy extends Human class. The object creation
        * can be done in this way. Parent class reference 
        * can have child class reference assigned to it
        */
       Human obj2 = new Boy();
   }
}
```

## Java 中的静态和动态绑定

如上所述，方法定义与方法调用的关联称为绑定。有两种类型的绑定：静态绑定和动态绑定。让我们讨论一下。

### 静态绑定或早期绑定

编译器在编译时可以解析的绑定称为静态或早期绑定。 static，private 和 final 方法的绑定是[编译时](https://beginnersbook.com/2013/04/runtime-compile-time-polymorphism/)。 **为什么？** 原因是无法覆盖这些方法，并且在编译时确定类的类型。让我们看一个例子来理解这个：

### 静态绑定示例

在这里，我们有两个类人类和男孩。这两个类都有相同的方法 walk（），但方法是静态的，这意味着它不能被覆盖，所以即使我在创建对象 obj 时使用了 Boy 类的对象，它也会调用父类方法。因为引用是 Human 类型（父类）。因此，每当静态，私有和最终方法的绑定发生时，类的类型由编译器在编译时确定，然后绑定发生在那里。

```java
class Human{
   public static void walk()
   {
       System.out.println("Human walks");
   }
}
class Boy extends Human{
   public static void walk(){
       System.out.println("Boy walks");
   }
   public static void main( String args[]) {
       /* Reference is of Human type and object is
        * Boy type
        */
       Human obj = new Boy();
       /* Reference is of HUman type and object is
        * of Human type.
        */
       Human obj2 = new Human();
       obj.walk();
       obj2.walk();
   }
}
```

输出：

```java
Human walks
Human walks
```

### 动态绑定或后期绑定

当编译器无法在编译时解析调用/绑定时，此类绑定称为动态绑定或后期绑定。 [方法覆盖](https://beginnersbook.com/2014/01/method-overriding-in-java-with-example/)是动态绑定的一个完美示例，因为覆盖父类和子类具有相同的方法，在这种情况下，对象的**类型确定要执行的方法。对象的类型在运行时确定，因此称为动态绑定。**

### 动态绑定示例

这是我们在上面看到的相同的例子。这里唯一的区别是，在这个例子中，覆盖实际上正在发生，因为这些方法是**而不是**静态，私有和最终。在覆盖的情况下，对覆盖方法的调用在运行时由对象类型确定，从而发生后期绑定。让我们看一个例子来理解这个：

```java
class Human{
   //Overridden Method
   public void walk()
   {
       System.out.println("Human walks");
   }
}
class Demo extends Human{
   //Overriding Method
   public void walk(){
       System.out.println("Boy walks");
   }
   public static void main( String args[]) {
       /* Reference is of Human type and object is
        * Boy type
        */
       Human obj = new Demo();
       /* Reference is of HUman type and object is
        * of Human type.
        */
       Human obj2 = new Human();
       obj.walk();
       obj2.walk();
   }
}
```

Output:

```java
Boy walks
Human walks

```

正如您所看到的那样，输出与我们在静态绑定示例中看到的不同，因为在这种情况下，在创建对象 obj 时，对象的类型被确定为 Boy 类型，因此调用 Boy 类的方法。请记住，对象的类型是在运行时确定的。

## 静态绑定与动态绑定

让我们讨论 Java 中静态和动态绑定之间的**差异。**

1.  静态绑定在编译时发生，而动态绑定在运行时发生。
2.  私有，静态和最终方法的绑定总是在编译时发生，因为这些方法无法被覆盖。当实际发生方法重写并将父类型的引用分配给子类类型的对象时，则在运行时期间解析此类绑定。
3.  [重载方法](https://beginnersbook.com/2013/05/method-overloading/)的绑定是静态的，并且重写方法的绑定是动态的。