The generic parameters Any of kotlin are converted to wildcards(?)
Asked Answered
W

2

21

I encountered an issue when I used kotlin and retrofit2,The generic parameters of kotlin are converted to wildcards(?),but not in java.

now, I need a parameter Map<String, Object>(The key is the String type, the value is not fixed) in java,convert to kotlin code is Map<String, Any>.

But retrofit treats them differently.

Map<String, Object> in java be compiled into [java.util.Map<java.lang.String, java.lang.Object>],and works correctly.

Map<String, Any> in kotlin be compiled into [java.util.Map<java.lang.String, ?>],and the retrofit2 throws parameterError(Parameter type must not include a type variable or wildcard).

1、Retrofit related code

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) method is quoted as follows

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

    }
    ……
}

2、interface in java, I need a parameter Map<String, Object>(The key is the String type, the value is not fixed), it be compiled into [java.util.Map<java.lang.String, java.lang.Object>],and works correctly.

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

3、interface in kotlin,I need a parameter Map<String, Any>(The key is the String type, the value is not fixed), but it be compiled into [java.util.Map<java.lang.String, ?>],and the retrofit2 throws parameterError(Parameter type must not include a type variable or wildcard).

@GET("/index.html")
fun getQueryMap(@QueryMap paramsMap: Map<String, Any>): Observable<ResponseBody>
Wellordered answered 31/7, 2017 at 7:9 Comment(1)
You can either use non-wildcard types (e. g. MutableMap, MutableList) or use @JvmSuppressWildcards annotation (e. g. @QueryMap paramsMap: @JvmSuppressWildcards Map<String, Any>).Incandescent
O
44

You simply have to add @JvmSuppressWildcards to your interface name.

@JvmSuppressWildcards
internal interface WebService {
    ...
}
Oram answered 24/9, 2018 at 9:26 Comment(0)
B
0

Replace this

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

with

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

Hope will solve the Issue...

Burgundy answered 6/12, 2021 at 20:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.