1、泛型的引入
集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object类型。当我们在取出每一个对象,并且进行相应的操作,这时必须采用类型转换。比如下面程序:
1 public class GenericDemo { 2 public static void main(String[] args) { 3 List list = new ArrayList(); 4 list.add("abc"); 5 list.add("love"); 6 list.add(5);//由于集合没有做任何限定,任何类型都可以给其中存放 7 //相当于:Object obj=new Integer(5); 8 9 Iterator it = list.iterator();10 while(it.hasNext()){11 //需要打印每个字符串的长度,就要把迭代出来的对象转成String类型12 String str = (String) it.next();//String str=(String)obj;13 //编译时期仅检查语法错误,String是Object的儿子可以向下转型14 //运行时期String str=(String)(new Integer(5))15 //String与Integer没有父子关系所以转换失败16 //程序在运行时发生了问题java.lang.ClassCastException17 System.out.println(str.length());18 }19 }20 }
2、泛型的定义和使用
1 /* 2 * JDK1.5 出现新的安全机制,保证程序的安全性 3 * 泛型: 指明了集合中存储数据的类型 <数据类型> 4 */ 5 6 public class GenericDemo { 7 public static void main(String[] args) { 8 function(); 9 }10 11 public static void function(){12 Collectioncoll = new ArrayList 数据类型>();13 coll.add("abc");14 coll.add("rtyg");15 coll.add("43rt5yhju");16 // coll.add(1);17 18 Iterator it = coll.iterator();19 while(it.hasNext()){20 String s = it.next();21 System.out.println(s.length());22 }23 }24 }
3、Java中的伪泛型
泛型只在编译时存在,编译后就被擦除,在编译之前我们就可以限制集合的类型,起到作用。例如:
ArrayListal=new ArrayList ();
编译后:
ArrayList al=new ArrayList();
4、泛型类
(1)定义格式
修饰符 class 类名 <代表泛型的变量> { } 例如,API中的ArrayList集合: class ArrayList{ public boolean add(E e){ } public E get(int index){ } } 代表泛型的变量>
(2)使用格式
创建对象时,确定泛型的类型 例如,ArrayListlist = new ArrayList (); 此时,变量E的值就是String类型 class ArrayList { public boolean add(String e){ } public String get(int index){ } } 例如,ArrayList list = new ArrayList (); 此时,变量E的值就是Integer类型 class ArrayList { public boolean add(Integer e){ } public Integer get(int index){ } }
5、泛型的方法
(1)定义格式
修饰符 <代表泛型的变量> 返回值类型 方法名(参数){ } 代表泛型的变量>
(2)泛型方法的使用
例如,API中的ArrayList集合中的方法: publicT[] toArray(T[] a){ } //该方法,用来把集合元素存储到指定数据类型的数组中,返回已存储集合元素的数组 使用格式:调用方法时,确定泛型的类型 例如: ArrayList list = new ArrayList (); String[] arr = new String[100]; String[] result = list.toArray(arr); 此时,变量T的值就是String类型。变量T,可以与定义集合的泛型不同 public String[] toArray(String[] a){ } 例如: ArrayList list = new ArrayList (); Integer[] arr = new Integer[100]; Integer [] result = list.toArray(arr); 此时,变量T的值就是Integer类型。变量T,可以与定义集合的泛型不同 public Integer[] toArray(Integer[] a){ }
6、泛型的接口
1 /* 2 * 带有泛型的接口 3 * 4 * public interface List{ 5 * abstract boolean add(E e); 6 * } 7 * 8 * 实现类,先实现接口,不理会泛型 9 * public class ArrayList implements List {10 * }11 * 调用者 : new ArrayList () 后期创建集合对象的时候,指定数据类型12 * 13 * 14 * 实现类,实现接口的同时,也指定了数据类型15 * public class XXX implements List {16 * }17 * new XXX()18 */19 public class GenericDemo2 {20 21 }
7、泛型的好处
(1)将运行时期的ClassCastException,转移到了编译时期变成了编译失败;
(2)避免了类型强转的麻烦。
1 public class GenericDemo { 2 public static void main(String[] args) { 3 Listlist = new ArrayList (); 4 list.add("abc"); 5 list.add("love"); 6 //list.add(5);//当集合明确类型后,存放类型不一致就会编译报错 7 //集合已经明确具体存放的元素类型,那么在使用迭代器的时候,迭代器也同样会知道具体遍历元素类型 8 9 Iterator it = list.iterator();10 while(it.hasNext()){11 String str = it.next();12 System.out.println(str.length()); //当使用Iterator 13 //控制元素类型后,就不需要强转了。获取到的元素直接就是String类型14 }15 }16 }
8、泛型的通配符
1 /* 2 * 泛型的通配符 3 */ 4 public class GenericDemo { 5 public static void main(String[] args) { 6 ArrayListarray = new ArrayList (); 7 8 HashSet set = new HashSet (); 9 10 array.add("123");11 array.add("456");12 13 set.add(789);14 set.add(890);15 16 iterator(array);17 iterator(set);18 }19 /*20 * 定义方法,可以同时迭代2个集合21 * 参数: 怎么实现 , 不能写ArrayList,也不能写HashSet22 * 参数: 或者共同实现的接口23 * 泛型的通配,匹配所有的数据类型 ?24 */25 public static void iterator(Collection coll){26 Iterator it = coll.iterator();27 while(it.hasNext()){28 //it.next()获取的对象,什么类型29 System.out.println(it.next());30 }31 }32 }
9、泛型的限定
1 /* 2 * 将的酒店员工,厨师,服务员,经理,分别存储到3个集合中 3 * 定义方法,可以同时遍历3集合,遍历三个集合的同时,可以调用工作方法 4 */ 5 import java.util.ArrayList; 6 import java.util.Iterator; 7 public class GenericTest { 8 public static void main(String[] args) { 9 //创建3个集合对象10 ArrayListcs = new ArrayList ();11 ArrayList fwy = new ArrayList ();12 ArrayList jl = new ArrayList ();13 14 //每个集合存储自己的元素15 cs.add(new ChuShi("张三", "后厨001"));16 cs.add(new ChuShi("李四", "后厨002"));17 18 fwy.add(new FuWuYuan("翠花", "服务部001"));19 fwy.add(new FuWuYuan("酸菜", "服务部002"));20 21 jl.add(new JingLi("小名", "董事会001", 123456789.32));22 jl.add(new JingLi("小强", "董事会002", 123456789.33));23 24 // ArrayList arrayString = new ArrayList ();25 iterator(jl);26 iterator(fwy);27 iterator(cs);28 29 }30 /*31 * 定义方法,可以同时遍历3集合,遍历三个集合的同时,可以调用工作方法 work32 * ? 通配符,迭代器it.next()方法取出来的是Object类型,怎么调用work方法33 * 强制转换: it.next()=Object o ==> Employee34 * 方法参数: 控制,可以传递Employee对象,也可以传递Employee的子类的对象35 * 泛型的限定 本案例,父类固定Employee,但是子类可以无限?36 * ? extends Employee 限制的是父类, 上限限定, 可以传递Employee,传递他的子类对象37 * ? super Employee 限制的是子类, 下限限定, 可以传递Employee,传递他的父类对象38 */39 public static void iterator(ArrayList array){40 41 Iterator it = array.iterator();42 while(it.hasNext()){43 //获取出的next() 数据类型,是什么Employee44 Employee e = it.next();45 e.work();46 }47 }48 }