suspend 함수는 왜 오버로딩이 안 될까?

송규빈·2024년 10월 30일
1
post-thumbnail

오버로딩이란?

오버로딩은 자바/코틀린에서 지원하는 기능입니다.
매개변수의 개수나 타입이 다르다면 메서드 명이 같아도 컴파일이 가능하다는 특징이 있습니다.
메서드 시그니처를 통해 오버로딩이 가능한 것입니다.

fun func() {

}

fun func(str: String) {

}

fun func(num: Int) {

}

fun func(num1: Int, num2: Int) {

}

suspend 함수는 왜 오버로딩이 안 될까?

코루틴을 접한 후 한 번도 생각해보지 않았던 질문입니다.

여러분은 아시나요?

suspend fun func() {

}

fun func() {

}

위 코드는 잘 동작할까요?
동작한다면 왜 잘 동작하는지 컴파일 에러가 난다면 왜 에러가 나는지 아시나요?

결과는 에러가 나옵니다.

궁금증을 가진 이유

위의 함수를 보면 당연히 컴파일 에러가 나올 것이라고 생각하실 수 있습니다.
저 또한 그래왔습니다.

하지만

문득 생각해보니 suspend 메서드는 내부적으로 Continuation 객체를 사용합니다.
디컴파일 해보면 매개변수로 Continuation 객체를 받을 수 있게 메서드가 선언되어 있습니다.

// suspend func() 디컴파일
   @Nullable
   public static final Object func(@NotNull Continuation $completion) {
      return Unit.INSTANCE;
   }

이 부분에서 궁금증이 생겼습니다.
suspend가 아닌 메서드의 경우는 아래와 같습니다.

public static final void func() {
   }

차이가 보이시나요? 분명히 Java코드에서 두개의 메서드 매개변수는 다릅니다.
즉, 자바 이론 상 메서드 시그니처가 다르므로 오버로딩이 가능합니다.

코틀린 동작과정

이유를 말하기에 앞서 동작과정을 살짝 찍먹해보면 좋을 것 같은데요.
코틀린은 코틀린 컴파일러가 코드를 파싱 및 타입 검사를 수행한 후 JVM이 이해할 수 있는 형태로 JVM 바이트 코드를 생성하고 JVM에서 실행됩니다.

그러므로

자바 컴파일러가 아닌 코틀린 컴파일러에서 코틀린 코드를 컴파일하므로 코틀린 코드에 대한 타입검사는 코틀린 컴파일러에서 이뤄집니다.
여기까지 생각하면 다시 처음 생각대로 코틀린 코드상 메서드 시그니처가 같으므로 당연히 컴파일 에러가 나오는 것입니다.

하지만

좀 더 명확하게 알고싶었습니다.
그래서 코틀린 공식 논의 페이지에 문의를 했고, 제 예상과 비슷한 답변이 돌아왔습니다.

오버로딩이 안 되는 이유

이유는 호출 시 두 선언이 충돌하기 때문이라고 합니다.
이에 대한 이견은 없습니다.

suspend fun func()fun func()가 선언이 되어있다면 func()이라는 함수를 호출할 때 어떤 것을 호출해야하는지 굉장히 난감한 상황이 오게 될 것입니다.

그래서 이를 코틀린 컴파일러 측에서 막아놓은 것입니다.
코틀린 컴파일러가 보기에는 suspend 키워드는 메서드 시그니처에 포함되지 않기 때문에 오버로딩이 불가한 것입니다.

profile
🚀 상상을 좋아하는 개발자
post-custom-banner

0개의 댓글