[英]Kotlin: Generic types in Kotlin
要获取要用于例如 json 反序列化的类定义,可以在 Kotlin 中使用以下内容:
Map::class.java
一个示例用法如下:
val map = mapper.readValue(json, Map::class.java)
但是现在如何定义泛型类型呢?
像这样的东西不能编译:
val map = mapper.readValue(decodedString, Map<String, String>::class.java)
所以我的问题是: *::class.java
的通用等价物是什么?
Class<T>
(在 Java 中)或KClass<T>
(在 Kotlin 中)只能表示classes ,而不是所有类型。 如果您使用的 API 仅使用Class<T>
或KClass<T>
,它根本不支持泛型类型(至少在那些函数中)。
相反, KType (或 Java 中的Type
)是用于表示包括泛型在内的完整类型信息的正确类型。 你可以这样使用它:
val myMapType: KType = typeOf<Map<String,String>>()
不幸的是, KType
没有类型参数(它不是KType<T>
),这使得它无法用于编译时类型检查:你不能拥有相当于fun deserialize(Input, KClass<T>): T
使用KType
而不是KClass
,因为您不能仅使用KType
参数为返回类型定义T
。
有几个技巧可以解决这个问题:
在 Java 和 Kotlin 中,一种方法是通过提供泛型超类并从其继承来通过继承获取此信息。
一般来说,序列化 API(尤其是反序列化部分)提供了使用它的解决方法,例如 Jackson 的TypeReference或 Gson 的TypeToken 。 它基本上是他们的Type
版本,但带有类型参数以具有一些编译时类型安全性。
在 Kotlin 中,有时根据情况还有另一种方法:使用具体类型参数。 使用内联函数,编译器可以在编译时了解更多关于类型参数的信息,方法是在内联函数体时将它们替换为调用站点的实际推断类型。 这允许像T::class
这样的东西在内联函数的主体中。 这就是你如何获得像typeOf这样的函数来获得KType
的方法。
一些 Kotlin 特定的反序列化库 API 使用内联函数来消除用户的麻烦,并直接获取类型信息。 这就是jackson-module-kotlin通过提供不带Class
参数的内联readValue
扩展来实现的,它具体化类型参数以获取目标类型信息
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.