【问题标题】:kotlin bound class reference and genericskotlin 绑定类引用和泛型
【发布时间】:2018-08-15 13:08:27
【问题描述】:

我正在切换到适用于 Android 的 Kotlin,但我很难理解泛型和绑定类引用的行为。 在 java 中,我可以使用 Moshi 的 lib 序列化一个对象,其中包含以下几行:

    Moshi moshi = new Moshi.Builder().build();
    String string = moshi.adapter(CredentialsResponse.class).toJson(body);

在 Kotlin 中:

    val moshi = Moshi.Builder().build()
    var string = moshi.adapter(CredentialsResponse::class.java).toJson(body)

如果我想从实例中获取类,我找到了两个选项,但一个不起作用,我不明白为什么: 此代码有效:

    fun testStack(body: CredentialsResponse) {
        val moshi = Moshi.Builder().build()
        var string = moshi.adapter(body.javaClass).toJson(body)
    }

但此代码显示类型不匹配错误

    fun testStack(body: CredentialsResponse) {
        val moshi = Moshi.Builder().build()
        var string = moshi.adapter(body::class.java).toJson(body)
    }

AFAIK,自 1.1 (https://kotlinlang.org/docs/reference/reflection.html#bound-class-references-since-11) 起允许此调用,那么我错过了什么?

【问题讨论】:

  • 你能发布确切的错误信息吗?你使用什么编译器版本?
  • 完成! @TheOperator

标签: android generics kotlin


【解决方案1】:

两者之间有细微的差别:

class K
val javaClass: JsonAdapter<K> = moshi.adapter(body.javaClass)
val classJava: JsonAdapter<out K> = moshi.adapter(body::class.java)

注意body::class.java标记为out

通过调用moshi.adapter(body::class.java).toJson(body),您尝试将body 作为in 参数传递

【讨论】:

    【解决方案2】:

    不同之处在于,正如@AlexeySoshin 所指出的,未绑定的类引用Foo::class 使用被引用类KClass&lt;Foo&gt; 的确切类型键入,而绑定的类引用使用out-projection 键入:@ 987654326@.

    造成这种差异是有充分理由的。当您通过其名称引用一个类时,您可以确保该引用评估的类标记准确地指定了被引用的类型。

    但是,当您获得类型为Foo 的表达式的绑定类引用时,该表达式可能会计算为Foo 的子类型的实例,并且类型标记的正确类型是KClass&lt;out Foo&gt;,这意味着确切地说,实际的类型参数可能是 Foo 或其子类型。

    有关绑定和未绑定类引用之间区别的另一个详细说明,请参阅此答案:(link)

    【讨论】:

    • 是的,T:Any 乍一看有点令人费解:)
    猜你喜欢
    • 2021-11-15
    • 1970-01-01
    • 2014-08-13
    • 2012-08-28
    • 2017-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-02
    相关资源
    最近更新 更多