防止Kotlin强制Java查看通配符类型

gla*_*ded 5 kotlin

这很好用:

class Wrapped<out T>(val value: T)

open class Wrapper<T> {
    fun wrap(map: T): Wrapped<T> = Wrapped(map)
}

class Wrapper2 : Wrapper<Map<String, String>>()

val wrapped: Wrapped<Map<String, String>> = Wrapper2().wrap(mapOf())
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试Wrapper2.wrap从Java 访问时,Map会返回一个通配符类型:

    Map<String, String> toWrap = new HashMap<>();
    Wrapped<Map<String, String>> result;
    result = new Wrapper<Map<String, String>>().wrap(toWrap); // ok
    result = new Wrapper2().wrap(toWrap); // NOT ok, returns Wrapped<Map<String, ? extends String>>
Run Code Online (Sandbox Code Playgroud)

我可以通过覆盖解决此wrapWrapper2与明确的类型.

为什么Wrapper2.wrap返回不同的类型Wrapper.wrap

Jay*_*ard 6

您可以在Kotlin参考中描述的泛型中使用通配符来抑制Kotlin ,其中它描述了@JvmSuppressWildcards注释(或该注释的反向@JvmWildcard).

来自文档:

另一方面,如果我们不需要生成它们的通配符,我们可以使用@JvmSuppressWildcards:

fun unboxBase(box: Box<@JvmSuppressWildcards Base>): Base = box.value
// is translated to 
// Base unboxBase(Box<Base> box) { ... }
Run Code Online (Sandbox Code Playgroud)

注意:@JvmSuppressWildcards不仅可以用于单个类型参数,还可以用于整个声明(如函数或类),从而抑制其中的所有通配符.