Java Kotlin泛型声明站点差异<;在T>;建设

Java Kotlin泛型声明站点差异<;在T>;建设,java,generics,kotlin,Java,Generics,Kotlin,我在读kotlin没有通配符(l)的原因。这一切都发生在申报地点。我们有和结构,它们应该取代通配符。我想我理解了的工作原理,但我在方面遇到了麻烦因此,在java中,我们可以编写如下内容: public List<? extends Number> list1; public List<? super String> list2; class Service { val container = Container(mutableListOf("1"

我在读kotlin没有通配符(l)的原因。这一切都发生在申报地点。我们有
结构,它们应该取代通配符。我想我理解了
的工作原理,但我在
方面遇到了麻烦
因此,在java中,我们可以编写如下内容:

public List<? extends Number> list1;
public List<? super String> list2;
class Service {
  val container = Container(mutableListOf("1", "2", "3"))
}
class Container<T>(var list1: MutableList<out T>)
public ListKotlin
List
并不等同于Java
List
。Java列表具有mutating函数,而Kotlin列表是只读的。Kotlin
MutableList
相当于Java列表

接下来,看看:它的类型参数是协变的(
out E
),并且声明站点差异不能被use site variance覆盖,这就是为什么不能有
列表的原因

此外,声明站点方差
out E
意味着
E
从不出现在
in
位置(没有
E
类型的函数参数,也没有
E
类型的可变属性),事实上,由于
List
是只读的,它不会将
E
带入其任何函数(*)

您可以将示例转换为使用:

class Container2(变量列表2:MutableList)
MutableList
接口具有其
E
不变量,并且
中的
在使用站点的投影与声明站点差异不冲突

(*)实际上,但仅使用注释标记的参数(该注释仅抑制方差冲突),可以找到有关它的更多信息


还有一句话:

这一切都发生在申报地点。我们有
结构,它们应该取代通配符

实际上,是使用站点差异取代了Java通配符。声明站点差异仅应用于类型参数声明(定义了类型的地方),如果是,则该类型的所有用法都会有该差异(例如,当您使用
列表
时,它实际上是一个
列表
,因为声明站点差异为
列表
)。因此,使用地点差异适用于泛型类型的特定用途

class Container2<T>(var list2: MutableList<in T>)