为了方便理解首先先创建3个类
public class A {
public void printA() {
}
}
public class B extends A {
public void printB() {
}
}
public class C extends B {
public void printC() {
}
}
public class GenericHolder<T> {
T t;
public void putItem(T item) {
t = item;
}
public T getItem() {
return t;
}
}
如果希望只取出,不插入,或者是方法的返回值是泛型参数没有 就使用? extends B
也叫做上边界通配符,协变
GenericHolder<? extends B> holder1 = new GenericHolder<>();
A a = new A();
B b = new B();
C c = new C();
holder1.putItem(a);//编译错误
holder1.putItem(b);//编译错误
holder1.putItem(c);//编译错误
A a1 = holder1.getItem();
B b1 = holder1.getItem();
C c1 = holder1.getItem();//编译错误
val holder1:GenericHolder<out B> = GenericHolder()
val a = A()
val b = B()
val c = C()
holder1.putItem(a)//编译错误
holder1.putItem(b)//编译错误
holder1.putItem(c)//编译错误
val a1: A? = holder1.item
val b1: B? = holder1.item
val c1: C? = holder1.item//编译错误
如果希望只插入,不取出,或者是方法的参数是泛型返回值没有 就使用? super B
也叫做下边界通配符,逆变
GenericHolder<? super B> holder2 = new GenericHolder<>();
A a = new A();
B b = new B();
C c = new C();
holder2.putItem(a);//编译错误
holder2.putItem(b);
holder2.putItem(c);
A a1 = holder2.getItem();//编译错误
B b1 = holder2.getItem();//编译错误
C c1 = holder2.getItem();//编译错误
val holder2:GenericHolder<in B> = GenericHolder()
val a = A()
val b = B()
val c = C()
holder2.putItem(a)/编译错误
holder2.putItem(b)
holder2.putItem(c)
val a1: A? = holder1.item //编译错误
val b1: B? = holder1.item / /编译错误
val c1: C? = holder1.item //编译错误
补充
kotlin中的*
MutableList<*> 表示的是 MutableList<out Any?>
Kotlin 中可以用UnsafeVariance注解打破编译器对in out的限制 但同时也会失去运行时的状态确认,参考 collections.kt
网友评论