一
集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object类型。当我们在取出每一个对象,并且进行相应的操作,这时必须采用类型转换。
由于集合中什么类型的元素都可以存储。导致取出时,如果出现强转就会引发运行时 ClassCastException。称为 类型转换异常
为了解决这个异常问题,使用集合时,必须明确集合中元素的类型。这种方式称为:泛型。
对于泛型的定义和使用
/*public classArrayList<E> * E:element 变量 * add(E e) * 明确:1.创建对象时 * ArrayList<String>() arr=new ArrayList<String>(); * arr.add(String str) * 2.实现或者继承的时候明确 * public class MyList<E> implements List<String> * MyList<String> my=new MyList<String>(); * my.add(String str) * * 泛型:伪泛型,在编译的时候不进class文件 * ,只在java代码中对你的集合存储数据类型进行约束 * */
使用泛型的好处:
将运行时期的ClassCastException,转移到了编译时期变成了编译失败。
避免了类型强转的麻烦。
二 泛型通配符
public static void main(String[] args) { ArrayList<String> arr=new ArrayList<String>(); arr.add("中国"); arr.add("java"); HashSet<Integer> set=new HashSet<Integer>(); set.add(1); set.add(2); bianli(arr); bianli(set); } //?泛型通配符,当你不确定的时候,可以用泛型通配符来占空 public static void bianli(Collection<?> col){ Iterator<?> it=col.iterator(); while(it.hasNext()){ System.out.println(it.next()); } }
需要注意的是:
当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。
三 泛型的限定
如果想要对被打印的集合中的元素类型进行限制,只在指定的一些类型,进行打印。就要用到泛型的限定
限定泛型的上限:
格式:? extends E (? 代表接收E类型或者E的子类型的元素)
限定泛型的下限:
格式:? super E (? 代表接收E类型或者E的父类型的元素)
//有四个类:员工类,经理类,服务员类,厨师类 work方法 //写一个方法,传入三个类 调用其work方法 public static void main(String[] args) { ArrayList<Manager> arr1=new ArrayList<Manager>(); Manager m=new Manager(); arr1.add(m); ArrayList<Waiter> arr2=new ArrayList<Waiter>(); Waiter w=new Waiter(); arr2.add(w); ArrayList<Cooker> arr3=new ArrayList<Cooker>(); Cooker c=new Cooker(); arr3.add(c); working(arr1); working(arr2); working(arr3); } public static void working(ArrayList<? extends Emp> arr){ Emp emp=arr.get(0); emp.work(); }
上面是一个例子,其中经理类,服务员类,厨师类都是员工类Emp的子类。