泛型:把类型明确的工作推迟到创建对象或调用方法的时候才去明确的特殊的类型。
为什么需要泛型?
我们知道使用Object可以来表示任意类型,但它向下转型有强转的问题,会导致程序不太安全。
在集合类中泛型随处可见,那么试想一下,如果集合类中没有泛型会是怎样的呢?因为Map这些集合对元素的类型没有任何限制,我把Dog对象或Cat对象扔进去集合中,集合也不知道元素类型是什么,只知道它们都是各Object的东西,所以在取出来时候得到的是Object对象,还需要进行强转。
泛型擦除
泛型是提供给javac编译器使用的,用于限定集合的输入类型,但编译器编译完带有泛型的java程序后,生成的class文件中将不再带有泛型信息, 以此使程序运行效率不受到影响,这个过程就是泛型的擦除。
还有当带有泛型特性的集合复制给老版本(没有泛型的)集合时候,也会把泛型擦除了。
为什么泛型类无法继承自Throwable异常类
try {
// may throws exception
doSomeStuff();
} catch (SomeException<Integer> e) {
doA();
} catch (SomeException<String> e) {
doB();
}
假设当前有两个类 —— SomeException<Integer>
类和 SomeException<String>
类,它们都是继承自 Throwable
类的。而上述代码中的 doSomeStuff()
方法可能是抛出 SomeException<Integer>
异常或 SomeException<String>
异常,我们针对不同的异常做出不同的逻辑操作。这样似乎没啥问题,但由于上面说过的类型擦除机制的存在,所以无论是 SomeException<Integer>
或者是 SomeException<String>
经过编译器的类型擦除后都将会变成 SomeException
。故上述代码是不可以运行的,因为当代码抛出异常时编译器是无法判断走哪个 catch
分支的,所以 java 为了避免这样的问题出现,故泛型类是无法继承自 Throwable
类的。
注意:是泛型类无法继承自 Throwable
,而并不是泛型不能继承自 Throwable。
//不合法,泛型类不能继承Throwable
public class CustomException<T> extends Throwable{}
//合法,泛型T可以继承自Throwable,这只是普通的限定符,和泛型类没啥关系
public class Test<T extends Throwable> {}
注意:泛型中的<Object>
并不是像以前那样有继承关系的,也就是说List<Object>
和List<String>
是毫无关系的!!!!