看到appcompat-v7-26
中findViewById
不用强制类型转换了(代码见下方), 虽然 findViewById
返回值添加<T extends View>
的方法我一直再用, 但是引用到官方Api还是26中才完成的.
所以想整理一下泛型的基础知识, 泛型的概念很简单, 贵在如何灵活使用
泛型 T
只要是大写字母就行, 意义是一样的
但是为了可读性, 情景如下
- E — Element,常用在java Collection里,如:List<E>,Iterator<E>,Set<E>
- K,V — Key,Value,代表Map的键值对
- N — Number,数字
- T — Type,类型,如String,Integer等等
使用情景①
class Point<T>{
private T x;
private T y
}
//新建实例
Point<Integer> integerPoint = new Point<Integer>();
Point<Float> floatPoint = new Point<Float>();
<>尖括号里面的泛型可以写多个,
class Point<T,U>{
T x;
U y;
}
//新建实例
Point<Integer,Float> p = new Point<Integer,Float>();
使用情景②
返回值中存在泛型
public <T extends View> T findViewById(@IdRes int id) {
return getDelegate().findViewById(id);
}
函数返回值是<T extends View>类型。
泛型变量其实跟String,Integer,Double等等的类的使用上没有任何区别,T只是一个符号,可以代表String,Integer,Double……这些类的符号,在泛型函数使用时,直接把T看到String,Integer,Double……中的任一个来写代码就可以了。唯一不同的是,要在函数定义的中在返回值前加上<T>标识泛型;
无边界通配符 ?
我们用上面的Point来举例子
//新建实例事我们可以这样做
Point<Integer> integer = new Point<Integer>();
Point<Float> floatPoint = new Point<Float>();
Point<long> longPoint = new Point<long>();
//当多了之后, 我们要创建很多个Point, 能行? 起名字会不会累死
? 通配符的意义就是它是一个未知的符号,可以是代表任意的类
Point<?> point;
point = new Point<Integer>();
point = new Point<Float>();
point = new Point<long>();
几个常见的问题
- <? extends T>和<? super T>的区别
- <? extends XXX>指填充为派生于XXX的任意子类的话,
- <? super XXX>则表示填充为任意XXX的父类!
- ? 和 T 有什么区别
? 只能填充泛型变量 T ,表示任何通配类型. ? 只能用于声明, 不能用于创建实例.
网友评论