2017-10-17 110 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>