2023. 10. 26. 17:41ㆍIT/Kotlin
코틀린에서 작성된 고차 함수, 특히 라이브러리의 인자로 람다를 전달하면 모두가 신경 쓸 것 없이 행복하다.
하지만 코틀린은 자바를 개선한 언어.. 심지어 JVM(자바 가상 머신) 위에서 돌아간다.
따라서 프로그램을 짜다보면 자바의 메서드를 쓰지 않을 수가 없다.
근데 이게 정말 귀찮게 하는 요소가 많다.
//자바 메서드 정의. Runnable은 함수형 인터페이스.
void postponeComputation(int delay, Runnable computation);
//코틀린에서 인자로 람다를 전달하여 호출.
fun handleComputation(id: String) {
postponeComputation(1000) { println(id) }
}
다행히 자바 메서드의 함수형 인터페이스 타입 파라미터에 람다를 전달하는 것이 허용된다.
그런데 문제는 람다에서 변수를 포획한다면, 메서드를 호출할 때마다 포획한 변수를 저장하기 위해 Runnable 함수형 인터페이스를 구현한 무명 클래스 객체가 생성되었다.
이거 완전 트롤아니야..
class HandleComputation$1(val id: String): Runnable {
override fun run() {
println(id)
}
}
컴파일 후, 생성된 클래스는 포획한 변수마다 그 값을 저장하기 위한 필드가 있고, 람다가 선언된 함수의 이름을 접두사로 하는 이름을 갖게 되었다.
하지만 기술의 발전 속도란..
인라인이 도입되면서 호출 지점에 람다 코드가 복사되었고, 무명 클래스 객체의 생성도 줄어들었다.
그리고 결론적으로는 컴파일러가 똑똑이가 되었다.
인라인 되지 않은 람다식은 LambdaMetafactory의 metafactory() 함수를 통해 재사용 가능한 람다 표현식이 생성되었고,
람다가 포함된 함수를 호출할 때마다 invokedynamic을 통해 생성된 람다식을 실행했다.
그럼에도 불구하고 일부 특정한 상황에서는 여전히 무명 클래스로 컴파일된다고 하니, 원리를 알아두면 좋을 것 같았다.
<혹여나 잘못된 정보가 존재한다면 댓글로 알려주세요>
'IT > Kotlin' 카테고리의 다른 글
Kotlin - Java, Extensions, Destructuring declaration, etc (1) | 2024.04.22 |
---|---|
Kotlin - Smart cast, Backing field, etc (1) | 2024.04.19 |
변경 가능한 외부 로컬 변수를 포획한 람다, 클로저 (0) | 2023.10.25 |