package com.hu.rookie;
import java.util.Objects;
public class Animal {
public static void main(String[] args) {
/**
* A(——子类...——>B)为A的继承体系的上界线
*/
C<? extends A> b = new C<D>(new D());//赋值给上界线的泛型
C<? extends A> b2 = new C<A>(new A());//赋值给上临界线泛型
// b.setA(new B());编译报错,可能实例泛型是子类,传入父类的实例类型给子类赋值会不兼容,所以set方法失效
b.setA(null);//null可以是可以赋值给任何引用类型所以不会报错
b.getA();//只能获取,因为实例泛型类型只能是父类引用泛型类型的子类型,子类实例可以自动赋值父类的引用
/**
* (A——...——>B(B为临界线,右边为越界类型)——>D)为A的继承体系的上界线
*/
C<? super B> b3 = new C<A>(new A());//赋值给下界线的泛型
C<? super B> b4 = new C<B>(new B());//赋值给下临界线的泛型
// C<? super B> b5 = new C(new D());//赋值给超出了下临界线的类型,编译报错
b3.setA(new B());//父类引用的泛型为子类实例泛型的子类或者是本与子类泛型相同的类型,所以子类型赋值给父类类型是兼容的不会报错。
B bb = (B) b4.getA();//子类引用泛型调用实例为父类泛型去的get()编译器不知道会获取什么类型的数据,于是强制转化
/**
* 总结:
* ? extends A:?必须是A的子类
* C<? super B>:?必须是B的父类
*
*/
}
}
class C {
T a;
public T getA() {
return a;
}
public void setA(T a) {
this.a = a;
}
public C(T a) {
super();
this.a = a;
}
}
class A {
}
class B extends A {
}
class D extends A {
}