最近看了些文章,写了一段代码:
我们知道在android中绑定控件最最烦人的地方就是要通过id找到对应的控件后,还要进行强制类型转换,真心烦人。有了上面那个方法,只要在我们的BaseActivity类中添加这个方法,在绑定控件的时候就不用再写什么乱七八糟的强制类型转化了,想来也是为我节省了不少时间。一般工作中,用到泛型的地方真的好少,除了常用的List, Set, Map,能用到泛型的地方屈指可数,于是我决定多了解下泛型这个自己了解不太深的部分。
1. 泛型的命名规范
E - Element,常用在Java Collection里,比如:list<E>, Iterator<E>, Set<E>等
K, V - 即Key, Value,常用在Map中,代表键值对
N - Number,数字
T - Type类型,比如String, Integer等等
命名的规范是方便统一,不是说必须这么写,只不过这样写的好处是使得不同的工程师在看相互的代码会更加易于理解。
2. 泛型的使用
使用泛型,我们又可以分为两个方面,一个方面是类级别的,另一个方面是函数级别的。
看下面的例子:
我们可以看到编译器报错了,接着我们看看:
我们只关注前两个提示的修复方法,第一个是给getE(T)添加类型参数,第二个是给getE(T)所在的类添加类型参数。
如下图所示:
方法的泛型<T>统统放在返回类型的前面,而类的泛型则放在类的后面。
3. 泛型参数的界限
有的时候,你希望你的泛型只能是某一部分的类型,比如我们最开始的那个函数,因为绑定界面,所以只能为View的子类型,所以有<T extends View>这样的写法,给泛型参数添加一个界限,定义的方式如下:
这里的extends表示的是子类型,不等同于继承,而BoundType可以为class,也可以为interface。不要写这种令人笑话的语句: 如果我们想为泛型参数添加多个限制范围,应该如何写呢?多重限制的一般格式为:
其中A可以为类或者接口,而之后的所有必须为接口,否则编译报错,这跟我们在java里面写的一般类的继承类似,extends必须要放在implements前面,否则编译报错。4. 泛型类和子类型
下面这种写法是OK的:
好,下面我们改改,那么这块也是否OK呢?
可以看到编译报错了,我们知道Integer是Number的子类,如下图:
但是我们用new ArrayList<Integer>()发现编译报错了。让我们看看编译器提示什么?
其实这里的重点就是参数可以是List的子类型,但是Number不能变,跟我们之前的侧重点不同,这里我们关注List,之前我们关注T,而Arraylist<Integer>并不是ArrayList<Number>的子类。当谨记之。