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에서는 기본적으로 가상)에 사용되며 재정의된 메서드를 바인딩하는 데 사용됩니다.