- < T extends A>:单个边界,A可以是类或接口,只能接收继承或者实现A的类型。
- < T extends A&B&…>:多个边界,A可以是类或接口,A之后的只能是接口。比如:<T extends A&B&C>里面,T必须继承A类型或实现A接口,并且必须实现B和C接口。
三、泛型的好处
3.1 代码更健壮
泛型将集合的类型检测提前到了编译期,保证错误在编译时就会抛出,基本上代码编辑器(Android Studio、IDEA等)在书写代码阶段给泛型传入错误类型就会报错。
在拥有泛型之前只能在运行时抛出类型转换异常(ClassCastException),代码十分脆弱。
// 泛型存在之前
// 集合里存入Fruit和Dog,编译不会报错
List fruits = new ArrayList();
fruits.add(new Fruit());
fruits.add(new Dog()); // X 错误的插入,直到运行时报错
// 泛型存在之后
List fruits = new ArrayList();
fruits.add(new Fruit());
fruits.add(new Dog());// X 编译时就会报错
3.2 代码更简洁
泛型省去了类型的强制转换。在没有泛型之前,集合内的对象都会被向上转型为Object,所以需要强转。
// 没有泛型之前,获取对象需要强转
Fruit fruit = (Fruit) fruits.get(0);
3.3 代码复用性强
泛型就是使用参数化类型,在一段代码上操作多种数据类型。比如:对几个类的处理,在逻辑上完全相同,那自然会想这段逻辑代码只写一遍就好了,所以泛型就产生了。
四、泛型的原理
泛型在JDK1.5才出现,为了向下兼容,虚拟机是并不支持泛型的,所以JAVA在编译阶段除了进行类型判断,还对泛型进行了擦除,于是所有的泛型在字节码里都变成了原始类型,和C#的泛型不同,JAVA使用的是伪泛型。