Java의 정적 바인딩과 동적 바인딩의 차이점

Mohammad Irfan 2023년10월12일
  1. Java의 정적 바인딩
  2. Java의 정적 바인딩 예
  3. Java의 동적 바인딩
  4. Java에서 동적 바인딩의 예
  5. Java의 정적 바인딩 및 동적 바인딩
Java의 정적 바인딩과 동적 바인딩의 차이점

이 자습서에서는 Java의 정적 바인딩과 동적 바인딩의 차이점을 소개하고 주제에 대해 안내하는 몇 가지 예제 코드를 나열합니다.

바인딩은 메서드 호출을 메서드 구현에 연결하는 것으로 정적 및 동적의 두 가지 유형이 있습니다. 다형성에 따르면 개체는 여러 형식을 가질 수 있으며 이러한 형식은 컴파일 타임이나 런타임에 확인할 수 있습니다.

정적 바인딩은 메서드 호출이 컴파일 타임에 메서드 구현에 연결될 때 발생합니다. 동적 바인딩은 런타임 중에 바인딩이 발생할 때 발생합니다. 이 두 가지 유형의 바인딩에 대해 자세히 알아보고 몇 가지 예를 살펴보겠습니다.

Java의 정적 바인딩

위에서 논의한 바와 같이 정적 바인딩은 컴파일 시간 동안 발생하는 바인딩입니다. 컴파일 타임 자체에서 발생하기 때문에 Early Binding이라고도 합니다.

정적 바인딩의 경우 컴파일러는 사용할 메서드 구현을 정확히 알고 있습니다. 바인딩을 위해 유형 또는 클래스 정보를 사용합니다. 메서드 오버로딩은 정적 바인딩의 예입니다.

자식 클래스는 정적, 최종 및 개인 메서드를 재정의할 수 없기 때문에 모든 정적, 최종 및 개인 메서드는 정적 바인딩을 사용합니다. 컴파일러는 컴파일 타임에 사용할 메서드 구현을 알고 있습니다. 컴파일러는 부모 클래스의 메서드를 재정의할 수 없다는 것을 알고 있기 때문에 항상 메서드의 부모 클래스 구현을 사용합니다.

또한 정적 바인딩은 오버헤드가 적기 때문에 성능이 더 좋습니다.

Java의 정적 바인딩 예

아래 코드에서 학교 클래스에는 정적 ringBell() 메서드가 있으며 이 클래스는 Classroom에 의해 확장됩니다. Classroom에는 ringBell() 메서드도 있습니다.

ringBell() 메서드는 정적이므로 컴파일러는 클래스 유형만 확인하고 할당된 개체 클래스를 고려하지 않습니다. 따라서 School 클래스를 사용하여 Classroom(School s2 = new Classroom())의 객체를 생성할 때 Classroom 클래스가 아니라 School 클래스의 구현이 고려됩니다.

class School {
  public static void ringBell() {
    System.out.println("Ringing the school bell...");
  }
}
class Classroom extends School {
  public static void ringBell() {
    System.out.println("Ringing the classroom bell...");
  }
}
public class Main {
  public static void main(String[] args) {
    School s1 = new School(); // Type is School
    s1.ringBell();
    Classroom c1 = new Classroom(); // Type is Classroom
    c1.ringBell();
    School s2 = new Classroom(); // Type is School
    s2.ringBell();
  }
}

출력:

Ringing the school bell...
Ringing the classroom bell...
Ringing the school bell...

Java의 동적 바인딩

컴파일러는 컴파일 타임에 사용할 구현을 모르기 때문에 동적 바인딩은 런타임에 바인딩을 해결합니다.

바인딩은 컴파일 시간이 아니라 런타임 중 나중 단계에서 확인되기 때문에 늦은 바인딩이라고도 합니다. 또한 동적 바인딩은 유형이나 클래스가 아닌 바인딩에 개체를 사용합니다. 메서드 재정의는 동적 바인딩의 예입니다.

Java에서 동적 바인딩의 예

아래 코드에서 ringBell() 메서드는 정적이 아니므로 재정의가 발생합니다. 컴파일러는 ringBell() 메서드의 어떤 구현을 사용해야 하는지 알지 못하므로 바인딩은 런타임에 확인됩니다.

런타임 시 객체는 생성에 사용된 유형이 아니라 고려됩니다. 따라서 School 클래스를 사용하여 Classroom의 개체를 생성하는 경우 School 클래스가 아니라 Classroom 클래스의 구현이 고려됩니다.

class School {
  public void ringBell() {
    System.out.println("Ringing the school bell...");
  }
}
class Classroom extends School {
  @Override
  public void ringBell() {
    System.out.println("Ringing the classroom bell...");
  }
}
public class Main {
  public static void main(String[] args) {
    School s1 = new School(); // Type is School and object is of School
    s1.ringBell();
    Classroom c1 = new Classroom(); // Type is Classroom and object is of Classroom
    c1.ringBell();
    School s2 = new Classroom(); // Type is School and object is of Classroom
    s2.ringBell();
  }
}

출력:

Ringing the school bell...
Ringing the classroom bell...
Ringing the classroom bell...

Java의 정적 바인딩 및 동적 바인딩

정적 바인딩은 컴파일 타임에 메서드 호출을 메서드 구현에 연결하는 것입니다. 반면에 동적 바인딩은 런타임 시 메서드 구현에 대한 메서드 호출의 연결입니다.

이 두 기술을 모두 아는 것은 다형성의 개념을 이해하는 데 중요합니다. 정적 바인딩은 정적, 최종 및 개인 메서드에서 사용됩니다. 이 바인딩은 오버로드된 메서드의 경우 작동합니다. 동적 바인딩은 가상 메서드(Java에서는 기본적으로 가상)에 사용되며 재정의된 메서드를 바인딩하는 데 사용됩니다.

관련 문장 - Java Method