Kotlin/Kotlin

kotlin interface default method

Junuuu 2024. 3. 5. 00:01

개요

Java8부터는 interface의 default method를 지원하지만 kotlin에서는 어떻게 활용해 볼 수 있을지에 대해 알아보고자 합니다.

 

문제 상황

No property betweenOsVer found for type ${EntityName}

 

JPA를 활용하기 위해서는 interface를 정의하지만 해당 interface 내부에 기본 구현을 적용하고 싶어 default method를 활용하였습니다.

 

default method를 활용하면 spring-data-jpa가 메서드의 이름을 기반으로 쿼리를 만들어주지 않기 때문에 

 

하지만 kotlin에서는 deafult method를 기본적으로 지원하지 않아 메서드 이름을 기반으로 쿼리를 만들어주려다가 약속된 네이밍이 아니기 때문에 위와 같은 에러메시지를 리턴하게 됩니다.

 

Kotlin 1.4

Kotlin 1.2부터는 interface의 default method를 지원하기 위해 @JvmDefault 어노테이션을 실험적으로 추가하였습니다.

하지만 해당 어노테이션은 모든 인터페이스에 한해 주석을 달아줘야 하는게 불편했기 때문에 Kotlin 1.4에서 Deprecated 되었습니다.

 

새로운 방법은 -Xjvm-default=all 옵션을 주거나 -Xjvm-default=all-compatibility의 컴파일 옵션을 제공하면 됩니다.

tasks.withType(KotlinCompile::class).all {
    kotlinOptions {
        jvmTarget = "11"

        // interface에 default method를 만들 수 있도록 하는 옵션 추가
        freeCompilerArgs = listOf("-Xjvm-default=all")
    }
}

gradle에 해당 설정을 추가해주면 해결할 수 있습니다.

 

확장함수로 해결하기

fun TestRepoisotry.getMyCustomValue(id: Long) = findByTestId(id).customValue ?: throw NotFoundException()

default method는 아니지만 확장함수를 활용하여 default method처럼 사용해 볼 수 있습니다.

 

 

 

 

참고자료

https://blog.jetbrains.com/kotlin/2020/07/kotlin-1-4-m3-generating-default-methods-in-interfaces/

https://findmypiece.tistory.com/263

https://stackoverflow.com/questions/53964192/jvmdefault-and-how-add-compiler-option

https://zorba91.tistory.com/340