1,泛型的基本语法:类名<具体类> 对象名 = new 类名<具体类>()。类型参数规范如下:
1),K键,比如映射的键,key的类型
2),V值,比如Map的值,value类型
3),E元素,比如Set<E>,Element表示元素,元素的类型
4),T泛型,Type的意思
2,泛型只保存在源文件中,class文件中不存在,也就是说在编译阶段就会丢失。比如:系统并不会为ArrayList<String>生成新的class类,也不会把它当做新的类来处理。也就是说泛型只是存在与编译阶段,实际上在运行生成的class文件时一样的,那么我们就可以通过跑反射来避开泛型。
3,对象实例化时不指定泛型,默认为:Object。不能用基本类型实例化泛型类型参数,例如List<int> linkin = null ; 编译报错。
4,泛型不同的引用不能相互赋值,加入集合中的对象类型必须与指定的泛型类型一致。
5,静态方法中不能使用类的泛型,如果泛型类是一个接口或抽象类,则不可创建泛型类的对象。
6,不能在catch中使用泛型,从泛型类派生子类,泛型类型需具体化。在web中的泛型DAO经常使用。
7,通配符不能添加元素List<?> 表示未知元素的List集合;这种带通配符的List仅表示各种泛型List的父类,并不能把元素添加入集合中。
8,泛型不能同时设置上限和下限
9,泛型和继承的关系:如果B是A的一个子类型(子类或者子接口),而G是具有泛型声明的类或接口,G<B>并不是G<A>的子类型!比如:String是Object的子类,但是List<String >并不是List<Object>的子类。关于上面这点,要和数组区分开来:[B] b是[A] a的子类,但是在泛型接口不行的。
10,在写泛型的方法时,要是只是泛型的类型参数不同,那么这2个方法就算是同一个方法。因为编译后的泛型就去掉了,所以当然是一个方法。
好了,最后补充一句话,一定要记住这句话,泛型设计有一个良苦用心就是说在敲代码的过程中,只要是没有出现未检查的警告,那么程序在运行的时候肯定是不会发生类型转换异常的。所以我们要养成良好的习惯,尽量不要抑制泛型警告。
1),K键,比如映射的键,key的类型
2),V值,比如Map的值,value类型
3),E元素,比如Set<E>,Element表示元素,元素的类型
4),T泛型,Type的意思
2,泛型只保存在源文件中,class文件中不存在,也就是说在编译阶段就会丢失。比如:系统并不会为ArrayList<String>生成新的class类,也不会把它当做新的类来处理。也就是说泛型只是存在与编译阶段,实际上在运行生成的class文件时一样的,那么我们就可以通过跑反射来避开泛型。
3,对象实例化时不指定泛型,默认为:Object。不能用基本类型实例化泛型类型参数,例如List<int> linkin = null ; 编译报错。
4,泛型不同的引用不能相互赋值,加入集合中的对象类型必须与指定的泛型类型一致。
5,静态方法中不能使用类的泛型,如果泛型类是一个接口或抽象类,则不可创建泛型类的对象。
6,不能在catch中使用泛型,从泛型类派生子类,泛型类型需具体化。在web中的泛型DAO经常使用。
7,通配符不能添加元素List<?> 表示未知元素的List集合;这种带通配符的List仅表示各种泛型List的父类,并不能把元素添加入集合中。
8,泛型不能同时设置上限和下限
9,泛型和继承的关系:如果B是A的一个子类型(子类或者子接口),而G是具有泛型声明的类或接口,G<B>并不是G<A>的子类型!比如:String是Object的子类,但是List<String >并不是List<Object>的子类。关于上面这点,要和数组区分开来:[B] b是[A] a的子类,但是在泛型接口不行的。
10,在写泛型的方法时,要是只是泛型的类型参数不同,那么这2个方法就算是同一个方法。因为编译后的泛型就去掉了,所以当然是一个方法。
public static void show(List<? extends Number> l){ } public static void show(List<? super String> l){ }
好了,最后补充一句话,一定要记住这句话,泛型设计有一个良苦用心就是说在敲代码的过程中,只要是没有出现未检查的警告,那么程序在运行的时候肯定是不会发生类型转换异常的。所以我们要养成良好的习惯,尽量不要抑制泛型警告。
风流子弟曾少年,多少老死江湖前。。。