【问题标题】:The generic parameters Any of kotlin are converted to wildcards(?)任何 kotlin 的泛型参数都转换为通配符(?)
【发布时间】:2017-07-31 07:09:06
【问题描述】:

我在使用kotlin和retrofit2时遇到了一个问题,kotlin的泛型参数被转换为通配符(?),但在java中没有。

现在,我需要一个java中的参数Map<String, Object>(key是String类型,值不固定),转换成kotlin代码是Map<String, Any>。

但改造对它们的处理方式不同。

Map<String, Object>在java中被编译成[java.util.Map<java.lang.String, java.lang.Object>],并且可以正常工作。

kotlin中的Map<String, Any>编译成[java.util.Map<java.lang.String, ?>],retrofit2抛出parameterError(参数类型不能包含类型变量或通配符)。

1、改造相关代码

public ServiceMethod build() {
    ……
    for (int p = 0; p < parameterCount; p++) {
        Type parameterType = parameterTypes[p];
        if (Utils.hasUnresolvableType(parameterType)) {
            throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s", parameterType);
        }
        ……
    }
    ……
}

Utils.hasUnresolvableType(parameterType)方法引用如下

final class Utils {
    ……
    static boolean hasUnresolvableType(Type type) {
        ……
        if (type instanceof WildcardType) {
            return true;
        }
        ……

    }
    ……
}

2、java中的接口,我需要一个参数Map&lt;String, Object&gt;(键为String类型,值不固定),编译成[java.util.Map&lt;java.lang.String, java.lang.Object&gt;],就可以正常工作了。

@GET("/index.html")
Observable<ResponseBody> getQueryMap(@QueryMap Map<String, Object> params);

3、kotlin中的接口,我需要一个参数Map&lt;String, Any&gt;(key是String类型,值不固定),但是编译成[java.util.Map&lt;java.lang.String, ?&gt;],retrofit2会抛出parameterError(参数类型一定不能包括类型变量或通配符)。

@GET("/index.html")
fun getQueryMap(@QueryMap paramsMap: Map<String, Any>): Observable<ResponseBody>

【问题讨论】:

  • 您可以使用非通配符类型(例如 MutableMap、MutableList)或使用@JvmSuppressWildcards 注释(例如@QueryMap paramsMap: @JvmSuppressWildcards Map&lt;String, Any&gt;)。

标签: kotlin retrofit2 any


【解决方案1】:

您只需将@JvmSuppressWildcards 添加到您的接口名称即可。

@JvmSuppressWildcards
internal interface WebService {
    ...
}

【讨论】:

    【解决方案2】:

    替换这个

    @GET("/index.html") fun getQueryMap(@QueryMap paramsMap: Map&lt;String, Any&gt;): Observable&lt;ResponseBody&gt;

    与

    @GET("/index.html") fun getQueryMap(@QueryMap paramsMap: HashMap&lt;String, Any&gt;): Observable&lt;ResponseBody&gt;

    希望能解决问题...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多