in 是什么
in
标明这个类是这个泛型的消费者,只进不出, 相当于 Java 的 ? super E
out
是什么
out
标明这个类是这个泛型的生产者,只出不进,相当于 Java 的 ? extends E
为什么需要这个两个标记
// 我们定义一个类
class MyList<T> {
void add(T t){}
}
MyList<CharSequence> charSequences;
MyList<String> strings = charSequences; // 无法编译通过
strings.add("name");
在 Java 中,这个代码是无法编译的,因为 MyList<String>
和 MyList<CharSequence>
是两个不同的类型。实际上我们应该是可以这样做的,因为 MyList
只有 add
方法,你把子类型添加到父类型的集合中是没有问题的。
我们看看 kotlin
怎么解决这个问题
class MyList<in T>{
fun add(t: T){}
}
val charSequences = MyList<CharSequence>()
val strings: MyList<String> = charSequences // 没有问题