咱们为何要使用泛型?javascript
在学习集合时,咱们都知道集合中是能够存听任意对象的,只要把对象存储集合后,那么这时他们都会被提高成Object类型。当咱们在取出每个对象,而且进行相应的操做,这时必须采用向下类型转换。这个时候就要注意了,很容易出现问题.html
public class GenericDemo { public static void main(String[] args) { Collection coll = new ArrayList(); coll.add("abc"); coll.add("itcast"); coll.add(5);//因为集合没有作任何限定,任何类型均可以给其中存放 Iterator it = coll.iterator(); while(it.hasNext()){ //须要打印每一个字符串的长度,就要把迭代出来的对象转成String类型 String str = (String) it.next(); System.out.println(str.length()); } } }
运行时会出现一下异常.
也就是说咱们虽然能够向集合中存听任意类型,可是对他进行相应方法的调用时,必须把他向下转成之前的类型.java
那么要咱们显然来记忆咱们存了什么类型进去是不靠谱的 ,怎么来解决这个问题呢?markdown
在JDK5以后,新增了泛型(Generic)语法,咱们能够指定类或方法支持泛型,这样咱们对一个集合就只能存进去对应泛型的类型了(这个泛型能够直接肯定是什么肯定的类,也能够预支地使用未知的类型。).而且编译时期就能够进行语法检查.ide
泛型:能够在类或方法中预支地使用未知的类型。咱们在建立对象时,将未知的类型肯定具体的类型。post
泛型能够用到类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。学习
1.泛型类ui
//表明泛型的变量能够随便定义,通常用 T,K,E... 修饰符 class 类名<表明泛型的变量> { } class ArrayList<E>{ public boolean add(E e){ } public E get(int index){ } .... }
2.含有泛型的方法spa
public class MyGenericMethod { public <T> void show(T t) { System.out.println(t.getClass()); } public <T> T show2(T t) { return t; } }
注意:
2.1.调用方法时,肯定泛型的类型,传递的是什么类型的参数,泛型就是什么类型
2.2. public 与 返回值中间的<.T>很是重要,能够理解为声明此方法为泛型方法。只有声明了<.T>的方法才是泛型方法,泛型类和接口中的使用了泛型的成员方法并非泛型方法.code
3.含有泛型的接口
修饰符 interface接口名<表明泛型的变量> { } public interface MyGenericInterface<E>{ public abstract void add(E e); public abstract E getE(); }
3.1什么时候肯定泛型的类型呢?
(1)、定义实现类时肯定泛型的类型,此时就会重写接口中的方法.
public class MyImp1 implements MyGenericInterface<String> { @Override public void add(String e) { // 省略... } @Override public String getE() { return null; } }
(2)、始终不肯定泛型的类型,直到建立对象时,肯定泛型的类型
public class MyImp2<E> implements MyGenericInterface<E> { @Override public void add(E e) { // 省略... } @Override public E getE() { return null; } } public class GenericInterface { public static void main(String[] args) { MyImp2<String> my = new MyImp2<String>(); my.add("aa"); } }
4.泛型的通配符
`
为何出现呢?
这是由于泛型不存在继承关系 Collection