1.JAVA为什么要用泛型:
泛型是在JDK1.5之后增加的,那么为什么要引用泛型这个支持呢?其实原因很简单:Java集合有个“缺点”---当你把一个对象“放进”集合之后,集合就会“忘记”这对象进来时候的数据类型,当我们需要再次取出该对象的时候,该对象的编译类型就变成了Object(这里需要提一下,其运行时的类型没有改变)。当我们需要取出其中的对象时候,需要进行强制类型转换,这样不仅会代码比较繁琐,也容易照成ClassCastExeception异常。
(1)举一个例子:编译时不检查类型导致的异常
package javatest; import java.util.ArrayList; import java.util.List; public class FanXing { public static void main(String[] args) { List strList=new ArrayList(); strList.add("字符串1"); strList.add("字符串2"); strList.add(4); for(Object obj:strList){ String str=(String)obj; System.out.println(str); } } }以上这段代码,在编译阶段是通过的,但是在运行阶段将会报ClassCastException异常,程序输出如下图:
这个错误原因时你将一个Integer对象“放进”了List集合中,运行时程序试图将Interger对象转换为String类型,所以报错。
(2)引入泛型就允许程序在创建集合时指定集合的元素类型,如List<String>,指这个List是String类型的,如果给这个List传值的时候,传入Interger类型的数字,在编译阶段就会报错,这样就使我们的代码更加健壮,也无需一些强制类型转换操作。如下面例子:
package javatest; import java.util.ArrayList; import java.util.List; public class FanXing { public static void main(String[] args) { List<String> strList=new ArrayList<String>(); strList.add("字符串1"); strList.add("字符串2"); //strList.add(4); for(String obj:strList){ String str=obj; System.out.println(str); } } }
2.为接口和类增加泛型声明
(1)定义接口增加泛型声明
package javatest; public interface List<T>{ int add(T t); }在上面这个接口里面,T可以作为类型使用,在add方法中T可以作为参数类型使用。
(2)可以为类增加泛型声明
public class FanXing<T>{
private T t;
public FanXing(T t){
this.t=t;
}
public T toInfo(){
return this.t;
}
public static void main(String[] args) {
FanXing<String> a=new FanXing("a");
FanXing<Double> b=new FanXing(3.22);
}
}
3.为带泛型声明的接口和类创建实现类或者派生子类
public class A extends FanXing<String>{ public String toInfo(){ return "父类的返回值"+super.toString(); } }这里需要注意的是: 在泛型的使用中,定义方法时可以声明数据形参<T>,调用方法时必须为这些形参传入实际的数据如<String>。但是在使用类和接口时也可以不为形参<T>传入实际参数如<String>。下面举个例子:
public class A extends FanXing{ return super.toInfo().toString(); }上面的例子中,toInfo()返回的是Object类型
4.静态方法,静态初始化块或者静态变量的声明和初始化中不能使用泛型形参。
5.在instanceof引入泛型时,程序运行时会清除泛型的类型信息
这时可以使用通配符?解决这个编译异常。
6.类型通配符"?"
先让我们看一个例子:
public class FanXing<T>{ private T t; public FanXing(T t){ this.t=t; } public static void ListTest(List<?> c){ for(int i=0;i<c.size();i++){ //省略代码 } } }
7.泛型知识的展望
其实泛型的基本常用知识介绍到这里已经差不多了,后续一些更深入的知识点如“设定类型形参的上限”等在平常日常开发中我没有运用到所以不做分析了。
8.贴一个泛型在实际项目中的运用
代码片段1:
代码片段2: