為了方便理解首先先創(chuàng)建3個(gè)類
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;
}
}
如果希望只取出,不插入,或者是方法的返回值是泛型參數(shù)沒(méi)有 就使用? extends B
也叫做上邊界通配符,協(xié)變
GenericHolder<? extends B> holder1 = new GenericHolder<>();
A a = new A();
B b = new B();
C c = new C();
holder1.putItem(a);//編譯錯(cuò)誤
holder1.putItem(b);//編譯錯(cuò)誤
holder1.putItem(c);//編譯錯(cuò)誤
A a1 = holder1.getItem();
B b1 = holder1.getItem();
C c1 = holder1.getItem();//編譯錯(cuò)誤
val holder1:GenericHolder<out B> = GenericHolder()
val a = A()
val b = B()
val c = C()
holder1.putItem(a)//編譯錯(cuò)誤
holder1.putItem(b)//編譯錯(cuò)誤
holder1.putItem(c)//編譯錯(cuò)誤
val a1: A? = holder1.item
val b1: B? = holder1.item
val c1: C? = holder1.item//編譯錯(cuò)誤
如果希望只插入,不取出,或者是方法的參數(shù)是泛型返回值沒(méi)有 就使用? super B
也叫做下邊界通配符,逆變
GenericHolder<? super B> holder2 = new GenericHolder<>();
A a = new A();
B b = new B();
C c = new C();
holder2.putItem(a);//編譯錯(cuò)誤
holder2.putItem(b);
holder2.putItem(c);
A a1 = holder2.getItem();//編譯錯(cuò)誤
B b1 = holder2.getItem();//編譯錯(cuò)誤
C c1 = holder2.getItem();//編譯錯(cuò)誤
val holder2:GenericHolder<in B> = GenericHolder()
val a = A()
val b = B()
val c = C()
holder2.putItem(a)/編譯錯(cuò)誤
holder2.putItem(b)
holder2.putItem(c)
val a1: A? = holder1.item //編譯錯(cuò)誤
val b1: B? = holder1.item / /編譯錯(cuò)誤
val c1: C? = holder1.item //編譯錯(cuò)誤
補(bǔ)充
kotlin中的*
MutableList<*> 表示的是 MutableList<out Any?>
Kotlin 中可以用UnsafeVariance注解打破編譯器對(duì)in out的限制 但同時(shí)也會(huì)失去運(yùn)行時(shí)的狀態(tài)確認(rèn),參考 collections.kt

image