1.什么是泛型?
一种安全地扩展程序适用范围的方式,可以避免强制类型转化产生的异常。
2.泛型的定义
定义在类层次上,在整个类范围内有效:
public class ClassName<T...>
定义在成员方法上:
public<T...> viod doSome(arg...)
定义在静态方法
public static<T...> void doSome(arg...)
泛型定义成员方法或者静态方法上只在方法范围内有效。
3.限制泛型可用型
- class ClassName<T extends anyClass>:用在泛型类定义时,向下限制泛型只接受anyClass类及其子类。
- GenericType<? super anyClass>:用在泛型使用时,向上限制泛型只接受anyClass及其父类,通常用作方法的形参。
- GenericType<? extends anyClass>:用在泛型使用时,向下限制泛型只能接受anyClass及其子类,通常用作方法的形参。
4.泛型擦除机制
java中的泛型信息只存在于编译阶段,编译完成后,在字节码中与运行期间被擦除,只保留定义时的原始类型。
public void listMethod(List<String> stringList) { } public void listMethod(List<Integer> intList) { }
以上两个方法,按照重载原理,方法名相同,参数类型不同,允许出现。由于泛型擦除机制,泛型List在字节码与运行期间擦除了泛型信息,变成原始类型,那么这两个在定义时参数类型不同的方法就变成了完全相同的两个方法,编译无法通过。
5.泛型使用限制
⑴静态变量与静态方法
静态变量不可以被定义为泛型类声明的泛型,静态方法中不可以出现泛型类声明的泛型,因为泛型类声明的泛型需要在对象创建时指定具体类型,而访问静态变量或者静态方式时,不需要创建对象,就不能指定泛型的具体类型。
public class TempTest<T> { public static <K> void doSome01(K t) { } }
静态方法自身可以定义泛型,在调用时指定具体类型即可。之所以静态方法能接受自身定义的泛型,不能接受泛型类定义的泛型,关键在于静态方法在调用时能够为自身泛型指定类型,不能为泛型类声明的泛型指定具体类型。
也可以这样理解,静态变量和静态方法为所有对象所共享,如果采用泛型类定义的泛型,每一个对象创建时都指定一个类型,那么静态变量和静态方法到底采用哪一种类型呢?无论采用哪一种类型,都违背了共享的设计目的。
⑵继承
B是A的子类并不意味着List<B>是List<A>的子类型,List<B>与List<A>之间不能进行类型转化。
⑶Object与原始类型
List<Object>不同于List(List<?>),List<Object>无法接受List<String>类型对象,而List原始类型可以。
⑷数组
数组不可以采用泛型定义,即不可以采用"T[] arr=new T[10]"的形式定义数组。
参考:
http://blog.csdn.net/qq_29227939/article/details/52674631
http://blog.csdn.net/sunxianghuang/article/details/51982979