(Kotlin) 제네릭 - 타입 파라미터 소거(erasure), inline 실체화(reified)
타입 파라미터 소거
[Kotlin] as와 타입 캐스팅. 런타임 에러. 타입 파라미터 소거(erasure)
런타임 타입 검사 : inline + reified (실체화한 타입 파라미터)
1
2
3
inline fun <reified T> isA(value: Any) = value is T
>>> isA<String>("a")
true
- 이게 가능한 이유는 인라인 함수는 함수 바디 코드가 함수 호출부에 삽입 되기 때문에, 타입 인자가 아니라 구체적인 타입을 사용할 수 있기 때문이다.
- 자바에서는
reified
를 사용하는inline
함수를 호출할 수 없다. - 자바에서는 코틀린 인라인 함수를 다른 보통 함수처럼 호출해버려서 타입 정보가 사라지기 때문이다.
- inline reified 함수 내에서 위 예제처럼 실제 타입간 비교 등을 작성하는 경우, 자바에서 함수 호출하는 식으로 불러버리면 T타입 정보가 사라져 타입 비교가 예상과 다르게 동작하게 된다. 그래서 아예 호출하지 못하게 만든 듯.
inline
이기 때문에, 코드 조각을 가능한 작게 유지하는 것이 좋다.
실체화한 타입 파라미터를 사용한 표준 라이브러리로는 filterIsInstance<T>()
가 있다.
1
2
3
>>> val li = listOf(1, "b", 3)
>>> li.filterIsInstance<Int>()
[1, 3]
클래스 참조(멤버 참조)와 연계해서 사용
1
2
3
4
5
inline fun <reified T: Activity> Context.startActivity() {
val intent = Intent(this, T::class.java)
startActivity(intent)
}
>>> startActivity<DetailActivity>() // 가독성 향상
reified 제약
일부는 실체화의 개념으로 인해 생기는 제약이며, 나머지는 코틀린이 실체화를 구현하는 방법에 의해 생기는 제약이므로 이후 해결될 수 있다.
T
의 인스턴스를 생성할 수 없다.T
의 동반 객체 메소드를 호출할 수 없다.- 실체화한 타입 파라미터를 요구하는 함수에 실체화하지 않은 타입 파라미터로 받은 타입을 넘길 수 없다.
- 클래스, 프로퍼티의 타입 파라미터를
reified
로 지정할 수 없다. inline
과 함께 사용해야 한다. 인라인 함수에만 사용할 수 있기 때문에 실체화한 타입 파라미터를 사용하는 함수는 자신에게 전달되는 모든 람다를 인라이닝한다. 그러나 람다를 인라이닝할 수 없는 상황이거나 성능 문제로 인라이닝하고 싶지 않은 경우noinline
변경자를 함수 타입 파라미터에 붙여서 인라이닝을 금지할 수 있다.
This post is licensed under CC BY 4.0 by the author.