코틀린 람다를 자바 API에 활용하는 방법
// Java
public class Button {
public void setOnClickListener(OnClickListener 1) { ... }
}
public interface OnClickListener {
void onClick(View v);
}
- Button 클래스는 setOnClickListener 메서드를 사용해 버튼의 리스너를 설정
- OnClick 메서드만 선언된 OnClickListener 인터페이스를 인자로 전달
// Java 8 이전
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
}
})
- 자바 8 이전의 자바는 무명 클래스 인스턴스를 생성해 인자로 전달
// Kotlin
button.setOnClickListener { view -> ... } // 람다의 view는 View 타입
- OnClickListener 인터페이스에 추상 메서드가 단 하나만 있기 때문에 이런 코드가 가능
함수형 인터페이스 functional interface 또는 SAM 인터페이스
추상 메서드가 단 하나만 있는 인터페이스
SAM
단일 추상 메서드 single abstract method
코틀린은 함수형 인터페이스를 인자로 취하는 자바 메서드를 호출할 때 람다를 넘길 수 있게 해주며, 이는 자바처럼 무명 클래스 인스턴스를 정의하고 활용할 필요가 없다.
자바 메서드에 람다를 인자로 전달
함수형 인터페이스를 인자로 원하는 자바 메서드에 코틀린 람다를 전달할 수 있다.
// Java
void postponeComputation(int delay, Runnable computation);
// Kotlin
postponeComputation(1000) { println(42) } // Runnable의 run 추상 메서드
- Runnable 타입의 파라미터를 받는 함수
- 코틀린에서 람다를 이 함수에 넘길 수 있으며, 컴파일러는 자동으로 람다를 Runnable 인스턴스로 변환
- Runnable 인스턴스는 Runnable을 구현한 무명 클래스의 인스턴스라는 뜻으로, 컴파일러는 이 무명클래스와 인스턴스를 생성
- 무명 클래스에 있는 유일한 추상 메서드를 구현할 때 람다 본문을 메서드 본문으로 사용
postponeComputation(1000, object : Runnable {
override fun run() {
println(42)
}
})
- Runnable을 구현하는 무명 객체를 명시적으로 만들어서 사용
- 객체 식을 함수형 인터페이스 구현으로 넘김
- 명시적으로 선언한 경우 메서드를 호출할 때마다 새로운 객체가 생성
// 프로그램 전체에서 Runnable의 인스턴스는 단 하나만 생성
postponeComputation(1000) { println(42) }
val runnable = Runnable { println(42) }
fun handleComputation() {
// 모든 handleComputation 호출에 같은 객체 사용
postponeComputation(1000, runnable)
}
- 람다를 사용할 경우 무명 객체를 메서드를 호출할 때마다 반복 사용
fun handleComputation(id: String) {
// handleComputation 호출할 때마다 새로운 인스턴스 생성
postponeComputation(1000) { println(id) }
}
- 주변 영역의 변수를 포획한다면 매 호출마다 같은 인스턴스를 사용 불가
- 주변 영역의 변수를 포획한 새로운 인스턴스를 생성
코틀린 inline 으로 표시된 코틀린 함수(컬렉션을 확장한 메서드 등) 에게 람다를 넘기면 코틀린은 무명 클래스와 인스턴스를 생성하지 않는다.
람다를 함수형 인터페이스로 명시적으로 변경
컴파일러가 자동으로 람다를 함수형 인터페이스 무명 클래스로 바꾸지 못하는 경우 SAM 생성자를 사용할 수 있다.
SAM 생성자
람다를 함수형 인터페이스의 인스턴스로 변환할 수 있게 컴파일러가 자동으로 생성한 함수
EX. SAM 생성자를 사용해 값 반환하기
fun createAllDoneRunnable(): Runnable {
return Runnable { println("All done!") }
}
createAllDoneRunnable().run()
All done!
- SAM 생성자는 그 함수형 인터페이스의 유일한 추상 메서드의 본문에 사용할 람다만을 인자로 받아서 함수형 인터페이스를 구현하는 클래스의 인스턴스를 반환
EX. SAM 생성자를 사용해 listener 인스턴스 재사용하기
val listener = OnClickListener { view ->
val text = when(view.id) {
R.id.button1 -> "First button"
R.id.button2 -> "Second button"
else -> "Unknown button"
}
toast(text)
}
button1.setOnClickListener(listener)
button2.setOnClickListener(listener)
- 람다로 생성한 함수형 인터페이스 인스턴스를 변수에 저장해 사용
728x90
'Kotlin' 카테고리의 다른 글
Coroutine (0) | 2024.02.13 |
---|---|
변수와 상수 (0) | 2023.11.02 |
수신 객체 지정 람다, with 와 apply (0) | 2023.09.08 |
지연 계산 Lazy 컬렉션 연산 (0) | 2023.09.06 |
컬렉션 함수형 API (0) | 2023.09.05 |