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.静态方法,静态初始化块或者静态变量的声明和初始化中不能使用泛型形参。
![](https://img-my.csdn.net/uploads/201708/31/1504170885_8181.png)
5.在instanceof引入泛型时,程序运行时会清除泛型的类型信息
![](https://img-my.csdn.net/uploads/201708/31/1504172080_4533.png)
这时可以使用通配符?解决这个编译异常。
![](https://img-my.csdn.net/uploads/201708/31/1504172082_9676.png)
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:
![](https://img-my.csdn.net/uploads/201708/31/1504178919_2155.png)
代码片段2:
![](https://img-my.csdn.net/uploads/201708/31/1504179101_1619.png)
![](https://img-my.csdn.net/uploads/201708/31/1504179422_2548.png)