Method Dispatch
어떤 메소드를 호출할 것인가를 결정하고 실행하는 과정을 의미합니다.
Method Dispatch의 종류에는 Static Method Dispatch와 Dynamic Method Dispatch가 있습니다.
Static Method Dispatch
컴파일 시점에 호출되는 메서드가 결정되는 Method Dispatch 입니다.
코드를 통해 살펴보겠습니다.
public class Dispatch {
static class Service {
void run(int number) {//(1)
System.out.println("run(" + number + ")");
}
}
public static void main(String[] args) {
new Service().run(1);
}
}
위 코드에서 main 메서드에서 실행되는 run() 메서드는 해당 프로그램이 컴파일 되는 시점에서 (1)이 실행될지를 알고 있습니다.
public class Dispatch {
static class Service {
void run(int number) {//(1)
System.out.println("run(" + number + ")");
}
void run(String msg) {//(2)
System.out.println("run(" + msg + ")");
}
}
public static void main(String[] args) {
new Service().run(1);
new Service().run("Dispatch");
}
}
(1)과 (2)는 이름과 Parameter의 개수가 똑같지만 Parameter의 타입이 다른 메서드입니다.
그러나 위의 경우에도 컴파일 시점에 어떠한 메서드가 실행될지 알고 있기 때문에 Static Method Dispatch에 속합니다.
Dynamic Method Dispatch
실행 시점에 호출되는 메서드가 결정되는 Method Dispatch 입니다.
public class Dispatch {
static abstract class Service {
abstract void run();
}
static class MyService extends Service {
@Override
void run() {//(1)
System.out.println("MyService.run()");
}
}
static class YourService extends Service {
@Override
void run() {//(2)
System.out.println("YourService.run()");
}
}
public static void main(String[] args) {
MyService myService = new MyService();
myService.run(); // (1)이 실행
YourService yourService = new YourService();
yourService.run(); // (2)가 실행
}
}
해당 코드에서는 myService.run()을 실행하면 (1)이, yourService.run()을 실행하면 2가 실행된다는 것이 컴파일 시점에 결정됩니다.
즉 위의 경우도 Static Method Dispatch 입니다.
그러나 다음 코드는 달라집니다.
public class Dispatch {
static abstract class Service {
abstract void run();
}
static class MyService extends Service {
@Override
void run() {//(1)
System.out.println("MyService.run()");
}
}
static class YourService extends Service {
@Override
void run() {//(2)
System.out.println("YourService.run()");
}
}
public static void main(String[] args) {
Service service = new MyService();
// = new MyService() 부분을 무시하고 아래 코드만 본다고 하자
service.run();
}
}
위 코드에서 new MyService() 부분을 보지 않는다고 하였을 때,
컴파일 시점에 service.run()은 (1)과 (2)중 어느 메서드를 실행할 것인지가 결정되지 않습니다.
이는 service의 타입이 Service, 즉 추상 클래스이기 때문에 컴파일 시점에 어느 클래스가 실행될 것인지 결정할 수 없는 것입니다.
실제 프로그램 실행 시에는 예상하셨겠지만 (1)이 실행됩니다.
이때 발생하는 것이 Dynamic Method Dispatch입니다.
실제 프로그램 실행 시에는 run() 메서드 호출 과정에서 (보이지는 않지만) receiver parameter가 전달됩니다.
receiver parameter는 클래스의 this에 해당하는 Object입니다.
위 코드에서는 MyService의 receiver parameter가 전달되기 때문에 (1)이 실행되는 것입니다.
'☕️ Java > 기본' 카테고리의 다른 글
[Java] Thread (1) - 프로세스와 쓰레드 (0) | 2022.07.09 |
---|---|
[Java] Double Dispatch란? (feat. Visitor Pattern) (0) | 2022.07.08 |
[Java] 리플렉션을 활용한 백준 자동 README 생성기 (0) | 2022.02.07 |
[Java] Method Signature와 Method Type (0) | 2022.02.06 |
[Java] String Constant Pool (0) | 2022.01.28 |