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>
インターフェース名に@JvmSuppressWildcards
を追加するだけです。
@JvmSuppressWildcards
internal interface WebService {
...
}