web-dev-qa-db-ja.com

汎用パラメーターAnyのkotlinはワイルドカード(?)に変換されます

Kotlinとretrofit2を使用したときに問題が発生しました。kotlinの汎用パラメーターはワイルドカード(?)に変換されますが、Javaでは変換されません。

今、私はJavaでパラメータMap<String, Object>(キーは文字列型であり、値は固定されていません)が必要です。kotlinコードに変換するのはMap<String, Any>です。

しかし、改造はそれらを異なって扱います。

Map<String, Object> in 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<String, Object>(キーは文字列型で、値は固定されていません)が必要です。これは、[Java.util.Map<Java.lang.String, Java.lang.Object>]にコンパイルされ、正しく機能します。

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

3、kotlinのインターフェイス、パラメータMap<String, Any>が必要です(キーは文字列型で、値は固定されていません)が、[Java.util.Map<Java.lang.String, ?>]にコンパイルされ、retrofit2はparameterError(パラメータ型は型変数またはワイルドカードを含めないでください)。

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

インターフェース名に@JvmSuppressWildcardsを追加するだけです。

@JvmSuppressWildcards
internal interface WebService {
    ...
}
10