本文通过一个样本演示了Kotlin巧妙地泛化泛型类型参数的能力。
因此,首先考虑一下Kotlin不支持此功能的世界,如果我们正在使用Jackson库将具有基于字符串的键和基于整数的值的JSON转换为Map,我将使用以下代码:
@Test
fun `sample parameterized retrieval raw object mapper`() {
val objectMapper = ObjectMapper()
val map: Map<String, Int> = objectMapper.readValue("""
| {
| "key1": 1,
| "key2": 2,
| "key3": 3
| }
""".trimMargin(), object : TypeReference<Map<String, Int>>() {})
assertThat(map).isEqualTo(mapOf("key1" to 1, "key2" to 2, "key3" to 3))
}
上面使用的TypeReference实现了一种称为超级类型令牌的模式,该模式允许通过子类捕获参数化类型的类型。 请注意在Kotlin中创建匿名子类的丑陋方式。
object : TypeReference<Map<String, Int>>() {}
我想做的是改为通过以下方式调用ObjectMapper:
@Test
fun `sample parameterized retrieval`() {
val om = ObjectMapper()
val map: Map<String, Int> = om.readValue("""
| {
| "key1": 1,
| "key2": 2,
| "key3": 3
| }
""".trimMargin())
assertThat(map).isEqualTo(mapOf("key1" to 1, "key2" to 2, "key3" to 3))
}
根据要返回的类型(左侧)来推断泛型类型参数。
这可以通过使用ObjectMapper上的扩展函数来实现,如下所示:
inline fun <reified T> ObjectMapper.readValue(s: String): T =
this.readValue(s, object : TypeReference<T>() {})
内联函数是此处能够验证通用类型参数的支持的核心–编译后,该函数将扩展到该函数调用的任何位置,因此第二个版本与测试的第一个版本完全相同但读起来比以前好多了。
请注意,Jackson已经在出色的jackson-module-kotlin库中实现了这些Kotlin扩展功能 。
翻译自: https://www.javacodegeeks.com/2018/01/kotlin-reified-type-parameters-sample.html