Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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>
like image 998
like Avatar asked Jul 31 '17 07:07

like


People also ask

What is type parameter in Kotlin?

The type parameter lets you specify exactly that—instead of “This variable holds a list,” you can say something like “This variable holds a list of strings.” Kotlin's syntax for saying “a list of strings” looks the same as in Java: List<String> . You can also declare multiple type parameters for a class.

What is wildcard in Java generic?

In generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific).

What is out type in Kotlin?

"Out" keyword is extensively used in Kotlin generics. Its signature looks like this − List<out T> When a type parameter T of a class C is declared out, then C can safely be a super type of C<Derived>. That means, a Number type List can contain double, integer type list.


1 Answers

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

@JvmSuppressWildcards internal interface WebService {     ... } 
like image 109
Abdul Hakeem Mahmood Avatar answered Sep 20 '22 03:09

Abdul Hakeem Mahmood