SAM 변환 (Gemini 답변)

Philipy (윤상필)·2025년 9월 15일

SAM 변환 (Single Abstract Method Conversion)

네, 정확하게 보셨습니다! 정말 예리하시네요.

결론부터 말씀드리면, 마지막에 있는 { } 블록이 바로 세 번째 인자인 Runnable에 해당하며, 이는 코틀린(Kotlin)의 매우 편리한 기능 덕분입니다.

이것을 이해하기 위해 코틀린의 두 가지 주요 특징을 아시면 좋습니다.

1. SAM 변환 (Single Abstract Method Conversion)

Java에서 Runnable처럼 단 하나의 추상 메서드만 가진 인터페이스를 "SAM(Single Abstract Method) 인터페이스"라고 부릅니다. Runnablerun() 메서드 하나만 가지고 있죠.

코틀린에서 이런 SAM 인터페이스를 사용하는 Java 메서드를 호출할 때, new Runnable() { ... } 과 같이 번거롭게 객체를 생성할 필요 없이, 메서드의 본문(body)에 해당하는 람다(lambda) 표현식 { }만 간단하게 전달할 수 있습니다.

코틀린 컴파일러가 { }를 보고 '아, 이건 Runnable 인터페이스의 run() 메서드를 구현한 것이구나!'라고 똑똑하게 알아서 변환해 줍니다.

2. 후행 람다 (Trailing Lambda)

코틀린에서는 함수의 마지막 인자가 람다 표현식일 경우, 그 람다를 괄호 ( ) 밖으로 빼낼 수 있습니다. 이는 코드를 훨씬 깔끔하고 읽기 쉽게 만들어 줍니다.

두 가지 기능의 조합

Service.kt에서 사용된 코드는 바로 이 두 가지 기능이 합쳐진 결과입니다.

// engine(String, String, Runnable)메서드 호출
manager.engine(notification.v2_hash, text_value) {
//이 블록 전체가 세 번째 인자인 Runnable입니다.
    //이 안의 코드가 바로 Runnable의 run()메서드에 들어갈 내용입니다.
Log.d(TAG, "재생 완료 콜백 수신")
    isPlaying.value = false
}

이 코드는 아래의 Java 코드와 100% 동일한 의미를 가집니다.

//위 코틀린 코드와 완전히 동일한 역할을 하는 Java코드
manager.engine(notification.v2_hash, text_Value, new Runnable() {
    @Override
    public void run() {
        Log.d(TAG, "재생 완료 콜백 수신");
        ttsPlaying.setValue(false);//코틀린의 isPlaying.value = false와 동일
}
});

보시는 것처럼, 코틀린의 문법 덕분에 new Runnable() 이나 @Override public void run() 같은 상용구를 모두 생략하고 핵심 로직에만 집중할 수 있게 된 것입니다.

요약:
네, 질문하신 내용이 모두 맞습니다. 함수 호출 시 마지막에 붙은 { } 블록은 세 번째 Runnable 인자이며, 코틀린이 제공하는 SAM 변환후행 람다라는 간결한 문법 덕분에 new Runnable() { } 과 같은 형태로 보이지 않을 뿐, 내부적으로는 동일하게 동작합니다.

profile
Tech Phase-smith, Karax wannabe

0개의 댓글