JAVA(기본)

메서드 오버로딩의 본질(컴파일러는 어떻게 메서드를 선택하는가)

AOIME 2026. 3. 23. 15:42

1.목표 

이 글의 목표는 단 하나다.

 

컴파일러의 선택 기준을 머리에 고정하는 것

  • println이 왜 편한지 이해하는 게 아니다.
  • "같은 이름인데 왜 이게 선택됐는지" 설명할 수 있어야 한다.

최종 목표 :

어떤 코드가 와도 

"왜 이 메서드가 선택됐는지 설명 가능" 상태

 

2. 내용

더보기

2.1 정의

메서드 오버로딩이란:

같운 이름 + 다른 파라미터 목록을 가진 메서드들

void test(int x)
void test(double x)

 

2.2 본질

오버로딩의 본질은 "편의성"이 아니다

컴파일러가 하나를 선택하는 규칙 시스템이다.

 

2.3 실행 흐름(스토리)

 

test(10);

 

1. 컴파일러가 test 메서드 전부 수집

2, 전달된 값 확인 -> 10 = int

3. 후보 비교

후보                         필요 조건

test(int)                      변환 없음

test(double)               int -> double 변환 필요

4. 판단

편환 없는 게 더 정확

5. 결과

test(int)

 

2.4 핵심 규칙 (이 한 줄이 핵심)

컴파일러는 "변환이 가장 적은 메서드"를 선택한다.

 

2.5 우선순위 구조

1. 정확히 일치(exact match)

2. 자동 형변환(widening)

3.박싱(int -> Integer)

4. 가변 인자 (varargs)

=> 위에서 아래로 갈수록 우선순위 낮음

 

 

헷갈리는 구간

void test(long x)
void test(double x)

test(10);

 

  • int -> long 가능
  • int -> double 가능
  • 둘 다 가능

그럼 ?

더 구체적인 타입 long 선택

3. 심화

더보기

3.1 왜 이런 구조인가(근원)

  • 컴파일러는 실행 전에 결정해야 한다.(정적 바인딩)
  • 실행 중 판단은 성능/ 안정성 문제 발생

결론 

예측 가능성을 위해 설계된 규칙

 

3.2 위험한 케이스

케이스 1 : null

void test(String x)
void test(object x)

test(null);

컴파일 에러(모호함)

 

케이스 2 : 박싱

void test(int x)
void test(Integer x)

test(10);

int 가 더 정확 -> test(int) 

 

케이스 3: 의도와 다른 호출

void test(double x)
void test (int x)

test(10L);

long -> double 가능

long int 불가능

test(double) 호출

 

 

3.3 설계 관점(실무 핵심)

잘못된 설계

void save(int id)
void save(long id)

 호출 시 혼란 발생

 

좋은 설계 

void saveUser(int id)
void saveOrder(long id)

의미로 분리

 

3.4 최종 기준(이걸 외우자)

1. 타입 확인

2. 가능한 후보 찾기

3, 변환 비용 비교

4. 가장 비용 적은 메서드 선택

 

결론 

- 오버로딩은 편한 기능이 아니라 

본질은 컴파일러가 타입 기반으로 하나를 선택하는 규칙이다.

 

728x90