나는 reified
키워드 의 목적을 이해하려고 노력하고 있으며 , 그것은 generics에 대한 반영을 가능하게합니다 .
그러나 내가 그것을 떠나면 그것은 잘 작동합니다. 언제 이것이 실제적인 차이를 만들지 설명 할 사람이 있습니까?
나는 reified
키워드 의 목적을 이해하려고 노력하고 있으며 , 그것은 generics에 대한 반영을 가능하게합니다 .
그러나 내가 그것을 떠나면 그것은 잘 작동합니다. 언제 이것이 실제적인 차이를 만들지 설명 할 사람이 있습니까?
답변:
reified
좋은 점fun <T> myGenericFun(c: Class<T>)
와 같은 일반 함수의 본문에서는 컴파일 타임에만 사용할 수 있지만 런타임에 지워 지기 때문에 myGenericFun
유형에 액세스 할 수 없습니다 . 따라서 함수 본문에서 일반 유형을 일반 클래스로 사용하려면에 표시된대로 클래스를 매개 변수 로 명시 적으로 전달 해야합니다 .T
myGenericFun
그래도 reified 로 inline
함수 를 작성하면 런타임에도 유형에 액세스 할 수 있으므로 추가 로 전달할 필요가 없습니다 . 마치 일반 클래스 인 것처럼 작업 할 수 있습니다 . 예를 들어 변수가의 인스턴스 인지 확인하고 싶을 때 쉽게 수행 할 수 있습니다 . T
T
Class<T>
T
T
myVar is T
이러한 유형 의 inline
함수 는 다음과 같습니다.reified
T
inline fun <reified T> myGenericFun()
reified
작동함수reified
와 함께 만 사용할 수 있습니다 . 이러한 함수는 컴파일러 가 함수의 바이트 코드 를 함수가 사용되는 모든 위치에 복사합니다 (함수가 "인라인"되어 있습니다). Refined Type으로 인라인 함수를 호출하면 컴파일러는 형식 인수로 사용 된 실제 형식을 알고 해당 클래스를 직접 사용하도록 생성 된 바이트 코드를 수정합니다. 같은 따라서 호출 된다 (유형 인수가 있다면 ) 바이트 코드와 런타임에.inline
myVar is T
myVar is String
String
얼마나 도움 reified
이 될 수 있는지 보여주는 예를 살펴 보겠습니다 . 우리는 대한 확장 기능을 만들 String
라고 toKotlinObject
시도는 함수의 제네릭 형식에 의해 지정된 유형으로 일반 코 틀린 객체에 JSON 문자열을 변환 할 수 있음 T
. com.fasterxml.jackson.module.kotlin
이를 위해 사용할 수 있으며 첫 번째 접근 방식은 다음과 같습니다.
a) 형식이없는 첫 번째 방법
fun <T> String.toKotlinObject(): T {
val mapper = jacksonObjectMapper()
//does not compile!
return mapper.readValue(this, T::class.java)
}
그만큼 readValue
메소드는 구문 분석해야하는 유형을 사용합니다 JsonObject
. Class
type 매개 변수 를 얻으려고 T
하면 컴파일러에서 " 'T'를 고정 형식 매개 변수로 사용할 수 없습니다. 대신 클래스를 사용하십시오."
b) 명시 적 Class
매개 변수를 사용한 해결 방법
fun <T: Any> String.toKotlinObject(c: KClass<T>): T {
val mapper = jacksonObjectMapper()
return mapper.readValue(this, c.java)
}
해결 방법으로 Class
of T
를 메서드 매개 변수로 만들 수 있으며이 매개 변수는에 대한 인수로 사용됩니다 readValue
. 이것은 작동하며 일반적인 Java 코드에서 일반적인 패턴입니다. 다음과 같이 호출 할 수 있습니다.
data class MyJsonType(val name: String)
val json = """{"name":"example"}"""
json.toKotlinObject(MyJsonType::class)
c) 코 틀린 방식 : reified
유형 매개 변수 inline
와 함께 함수 사용reified
T
다르게 구현할 수 있습니다.
inline fun <reified T: Any> String.toKotlinObject(): T {
val mapper = jacksonObjectMapper()
return mapper.readValue(this, T::class.java)
}
테이크 할 필요가 없습니다 Class
의 T
추가는,T
일반 수업처럼 사용할 수 있습니다. 클라이언트의 경우 코드는 다음과 같습니다.
json.toKotlinObject<MyJsonType>()
reified
유형이 인라인 된 함수 는 Java 코드 에서 호출 할 수 없습니다 .
단순한
* 컴파일 시점에 사용 권한을 부여하는 것입니다 (함수 내부의 T에 액세스하기 위해)
예 :
inline fun <reified T:Any> String.convertToObject(): T{
val gson = Gson()
return gson.fromJson(this,T::class.java)
}
같은 사용 :
val jsonStringResponse = "{"name":"bruno" , "age":"14" , "world":"mars"}"
val userObject = jsonStringResponse.convertToObject<User>()
println(user.name)