繁体   English   中英

Kotlin:Kotlin 中的泛型类型

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM