java-jdk-type

79 阅读1分钟

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>();