2017-10-17 156 views
3

我正在爲我的android項目嘗試在Kotlin語言中實現一些特定的GSON TypeAdapter。在Kotlin中使用TypeAdapter實現TypeAdapterFactory

我現在面臨的問題是編譯誤差不能推斷類型:Type inference failed: 'T' cannot capture 'in (T..T?'. Type parameter has an upper bound 'Enum<T>' that cannot be satisfied capturing 'in' projection

的代碼如下:

class SmartEnumTypeAdapterFactory(fallbackKey: String) : TypeAdapterFactory { 

    private val fallbackKey = fallbackKey.toLowerCase(Locale.US) 

    override fun <T : Any> create(gson: Gson?, type: TypeToken<T>): TypeAdapter<T>? { 
     val rawType = type.rawType 
     return if (!rawType.isEnum) null else SmartEnumTypeAdapter(rawType) 
    } 

    class SmartEnumTypeAdapter<T : Enum<T>>(classOfT: Class<T>) : TypeAdapter<T>() { 

     override fun write(out: JsonWriter?, value: T) { 
      TODO("not implemented") 
     } 

     override fun read(`in`: JsonReader?): T { 
      TODO("not implemented") 
     } 
    } 
    } 

我想有classOfT: Class<T>作爲參數TypeAdapter的原因是出這個問題的背景。

+0

這是一個真正棘手的情況下......您是否嘗試過用Java實現這個東西?因爲那時你可以轉換爲Kotlin,看看它是否有效,但到目前爲止,我還沒有得到這兩種語言的工作。 – Robin

回答

0

這是不可能的,因爲您覆蓋的方法(TypeFactory.create)沒有上限(其轉換爲Kotlin中的<T : Any>)。在你的create方法中,T不是 保證是Enum<T>(所以,它不可能作爲參數傳遞給你的適配器)。

你可以做的只是刪除適配器類中的上限並保持私有狀態,以確保只有你的工廠可以創建它的實例(並且工廠已經驗證類型是枚舉)。

class SmartEnumTypeAdapterFactory(fallbackKey: String) : TypeAdapterFactory { 

    private val fallbackKey = fallbackKey.toLowerCase(Locale.US) 

    override fun <T> create(gson: Gson?, type: TypeToken<T>): TypeAdapter<T>? { 
     val rawType = type.rawType 
     return if (!rawType.isEnum) null else SmartEnumTypeAdapter(rawType) 
    } 

    private class SmartEnumTypeAdapter<T>(classOfT: Class<in T>) : TypeAdapter<T>() { 

     override fun write(out: JsonWriter?, value: T) { 
      TODO("not implemented") 
     } 

     override fun read(`in`: JsonReader?): T { 
      TODO("not implemented") 
     } 
    } 
} 

classOfTClass<in T>因爲TypeToken.rawType()返回Class<? super T>