Languages

java 함수에 kotlin lambda 식 메소드로 전달하기 (자바 함수형 인터페이스)

!쪼렙조햄 2020. 4. 26. 21:54
반응형

자바 함수형 인터페이스 활용

  • 코틀린 lambda를 java API에 사용할 수 있다
  • SAM 인터페이스 == functional interface
    • single abstract method : 단일 추상 메소드
    • interface에 추상 메소드가 하나만 있는 경우에 사용가능 ?
    • java로 작성한 functional interface에서만 동작
    • SAM conversions이 동작하면 lambda 식을 사용할 수 있다

👨‍👨‍👧‍👦 자바 메소드에 람다를 인자로 전달

// java
public interface OnClickListener {
    void onClick(View v);
}

// kotlin
button.setOnClickListener { v -> ...}
// java
void postponeComputation (int delay, Runnable computation);

// kotlin - 1
postponeComputation(1000){println(42)}

// kotlin - 2
postponeComputation(1000, object : Runnable {
    override fun run(){
    println(42)
  }
})
  • java에서 postponeComputation이라는 함수를 만든다
  • kotlin에서 java 메소드에 코틀린 람다 함수를 전달한다
    • 컴파일러는 kotlin lambda function을 'Runnable을 구현한 무명 클래스의 인스턴스'로 만들어준다
      • 내부적으로 람다식은 익명클래스로 치환된다
    • Runnable instance는 한번 만들어진다
    • 다만, 람다가 주변 영역의 변수를 포획한다면 매 호출마다 같은 인스턴스를 사용할 수 없다
      • 매번 객체가 생성되어 사용된다
  • kotlin - 2
    • Runnable을 구현하는 무명 객체를 명시적으로 만들어서 사용
    • 이 경우에 postponeComputation 실행할 때마다 객체가 만들어지게 된다
  • 대부분의 코틀린 확장함수는 inline function으로 정의되어 있다
    • 그래서 대부분 lambda expression을 인자로 받고, 무명 객체를 생성하여 사용하지 않는다
    • inline function은 컴파일시 해당 코드가 호출부분으로 그대로 복사되어 들어가기 때문
      • inline function : 코틀린 특성 (8장에 설명)

👨‍👧‍👦 SAM 생성자 : 람다를 함수형 인터페이스로 명시적으로 변경

  • SAM 생성자
    • 람다를 함수형 인터페이스의 instance로 사용할 수 있도록 컴파일러가 생성한 함수
    • 컴파일러가 자동으로 람다를 함수형 인터페이스 무명 클래스로 변경하지 못하는 경우 SAM 생성자를 사용할 수 있다
      • 예시
        • 함수형 인터페이스의 인스턴스를 반환하는 메소드가 있는 경우
        • 람다를 직접 반환할 수 없고, 반환하고픈 람다를 SAM 생성자로 감싸야 한다
fun createAllDoneRunnable(): Runnable{
    return Runnable {println("All done!")}
}

createAllDoneRunnable().run()
  • SAM 생성자의 이름 == 사용하려는 함수형 인터페이스의 이름

Reference

반응형