type
type
Class<T> implements java.io.Serializable,GenericDeclaration,Type,AnnotatedElement=> class implements Type
- ParameterizedType: 参数化类型(函数参数类型化:
<T> func(T t)) - GenericArrayType: 通用Type,泛型的数组;
T[] value - WildcardType: 外卡(未知?)Type
<?>; <? extends Enumbers> - TypeVariable: 未编译前的信息,
{ K key, V value }=> 类型defination时的信息,不是编译后确定的类型
T
泛型编程\泛型擦出
编译时擦出/确定
接口\类\方法
// 泛型接口
public interface IHello<T>{}
// 泛型类,双范型
public class Hello<T,E>{}
// 方法:<T>标记是泛型方法
public <T> T getFirst(T[] ts) {
return ts[0];
}
// 泛型类Class<T>, 用户创建实例
public static <T> T getInstance(Class<T> t) {return t.newInstance();}
使用类型
- T: 确定类型
- ?: 无界类型
- < ? extends T> 上界:
T t = < ? extends T>.get() - < ? super T > 下界:
<? super T>.set(T t)
使用原则
PECS即Producer extends Consumer super; 通俗理解:<? extends T> function(<? super T> t){}
- 从集合中取元素, 使用< ? extends T> 通配符; producer用来取出元素
- 向集合中放元素, 使用< ? super T> 通配符; consumer用来放入元素
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
// 放进去消费T,泛型需要选择T的父类
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
? and Object
-
List lt=new ArrayList();指定集合元素只能是T类型
-
List< ? > lx=new ArrayList<>(); 没有指定集合的类型,不能使用get/set任何元素
-
List< ? extends T> let = new ArrayList();
- 初始化时,X是T或T的子类
- get() 方法可以使用多态
- set(y)
不能确定哪个子类,复制会编译失败
-
List< ? super T> get = new ArrayList();
- 初始化时,X是T或T的父类
- get() 不能使用多态,只能使用
Object obj = get.get(); - set(y) 可以使用多态,
y是X的子类
Fruit fruit = new Apple(); // 没有问题
List<Fruit> list = new ArrayList<Apple>(); // 编译不通过;因为List<Fruit>不是List<Apple>的父类
List<? super Apple> = new ArrayList<Apple>(); // 正确使用
List<Object> = new ArrayList<Apple>();