【问题标题】:POJO class mismatchPOJO 类不匹配
【发布时间】:2018-11-19 11:56:39
【问题描述】:

我有以下类 User 扩展了 BaseResponse 类。一世 收到类型不匹配错误:
必需 => String
找到 => String.Companion

用于返回 apiKey

package com.touchsides.rxjavanetworking.network.model

import com.google.gson.annotations.SerializedName

class User: BaseResponse()
{

    @SerializedName("api_key")
    val apiKey = String

    fun getApiKey(): String
    {
        return  apiKey
    }
}

abstract class BaseResponse(var error: String?=null)
{


}

这个错误的当前实现如何

【问题讨论】:

  • 简单的错字val apiKey = String 你的意思是val apiKey: String

标签: kotlin


【解决方案1】:

您在声明api_key (apiKey = String) 时使用了= 而不是:。这实际上意味着您正在使用 String.Companion 对象初始化 api_key

而且您不需要创建 getApiKey() (getter) 方法,因为默认情况下您的属性将拥有 getter 方法。

class User : BaseResponse() {

    @SerializedName("api_key")
    var apiKey: String? = null
        private set

}

abstract class BaseResponse(var error: String? = null)

事实上你可以使用data class来达到这个目的

data class User(@SerializedName("api_key") val apiKey: String):BaseResponse()

fun main(args: Array<String>) {
    Gson().fromJson<User>("{\"api_key\":\"my api key\"}", User::class.java).let {
        println(it.apiKey)
    }
}

【讨论】:

    【解决方案2】:

    一个完整的答案是你的代码应该是这样的:

    class User: BaseResponse()
    {
        @SerializedName("api_key")
        lateinit var apiKey: String  // must be set by something before being read
    }
    
    abstract class BaseResponse(var error: String?=null) {
    }
    

    如果您打算稍后通过反序列化设置apiKey 属性,则不需要默认值,如果不需要,则还应添加默认值,如下所示。 getApiKey() 方法已被删除,因为您在 Kotlin 中不需要它,所有属性都有 automatically generated getters 内置的,并且通过添加您自己的方法,您最终会在生成的 getter 和您手动创建的 getter 之间产生冲突(两个具有相同名称,相同签名的方法)。

    如果您确实需要 apiKey 的默认值,请使用 var 以便反序列化可以工作(如果您打算这样做)并添加默认空字符串或使其成为可为空的字符串并将其设置为null.

    class User: BaseResponse()
    {
        @SerializedName("api_key")
        var apiKey: String = ""     // if you want a default regardless, or make it nullable and null
    }
    
    abstract class BaseResponse(var error: String?=null) {}
    

    【讨论】:

      【解决方案3】:

      你被 Java 做事的方式困住了。在 kotlin 中定义 GetterSetter 时,您不必自己编写它们。一旦你声明了一个变量,这两种方法都会被自动创建。

      编辑:所以删除 POJO 类中的 getter。

      【讨论】:

      • @Jayson Minard 你错了。我在我的一个项目中使用了它,它工作正常。再三考虑,解释为什么它不适用于 OP。
      • 这取决于反序列化的工作方式,如果它使用反射并抓取字段并在不通过 setter 的情况下做一些危险的事情,那么它可能会在其中填充一个值。许多反序列化器不会,他们会将其视为只读而不设置它。 Kotlin 特定的肯定不会。序列化可以正常工作,这是另一个方向。
      • 因此您可以依靠一些 Java 代码进行反射填充的运气,或者您可以将其设为 lateinit var apiKey: String 并使用针对此特定用例的机制。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-11
      • 1970-01-01
      • 2014-02-05
      • 2018-06-08
      相关资源
      最近更新 更多