5. [4] 자바 함수형 인터페이스 활용

  • Kotlin에서 사용하는 대부분의 API들은 자바로 작성되어 있다.
  • 하지만, Kotlin의 람다를 Java API에 사용하더라도 큰 문제는 없다.
  • 자바 8 이후로는 무명 클래스 인스턴스 대신 람다를 넘길 수 있다.

(1) 자바 메서드에 람다를 인자로 전달

  • 함수형 인터페이스를 인자로 원하는 자바 메서드에 코틀린 람다를 전달할 수 있다.
  • 람다에 대해 무명 클래스를 만들고, 그 클래스의 인스턴스를 만들어서 메서드에 넘기는 것은 함수형 인터페이스를 받는 자바 메서드를 코틀린에서 호출할 떄 쓰는 방식을 설명해주지만, 컬렉션을 확장한 메서드에 람다를 넘기는 경우에는 사용하지 않는다.
  • inline으로 표시된 코틀린 함수를 람다에게 넘기면 아무 무명 클래스도 만들어지지 않는다.

(2) SAM 생성자: 람다를 함수형 인터페이스로 명시적 변경

fun createAllDoneRunnable(): Runnable {
  return Runnable{ println("All Done!") }
}
createALlDoneRunnable().run()
// All Done!
  • SAM 생성자는 람다를 함수형 인터페이스의 인스턴스로 변환할 수 있게 컴파일러가 자동으로 생성한 함수이다.
  • 컴파일러가 자동으로 변경하는 것이 불가능한 경우, SAM 생성자를 사용할 수 있다.
  • SAM 생성자의 이름은 사용하려는 함수형 인터페이스의 이름과 같다.
  • 이는 유일한 추상 메서드의 본문에 사용할 람다만을 인자로 받아서 함수형 인터페이스로 구현하는 클래스의 인스턴스를 반환한다.
  • 람다로 생성한 함수형 인터페이스 인스턴스를 변수에 저장하고 싶은 경우에도 이를 사용할 수 있다.
val listener = OnClickLisetener { view ->
  val text = when(view.id) {          // view.id를 통해 어떤 버튼이 클릭되었는지 판단한다.
    R.id.button1 -> "First Button"
    R.id.button2 -> "Second Button"
    else -> "Unknown Button"
  }
  toast(text)     // text의 값을 사용자에게 보여준다.
}
  • Listener는 어떤 버튼이 클릭 되었는지에 따라 적절한 동작을 수행한다.
  • OnClickListener를 구현하는 것이 객체 선언을 통해 리스너를 만들 수 있지만, SAM 생성자를 사용하는 것이 편하다.