泛型浅析与应用

来源:互联网 发布:linux cron命令每周三 编辑:程序博客网 时间:2024/06/16 07:34

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++){//省略代码}}}

其中List<?>代表这个List的元素类型是未知的,这个问号被叫做通配符,它的元素类型可以匹配任何类型。一般来说带有通配符的类都是作为父类来使用。

7.泛型知识的展望

    其实泛型的基本常用知识介绍到这里已经差不多了,后续一些更深入的知识点如“设定类型形参的上限”等在平常日常开发中我没有运用到所以不做分析了。

8.贴一个泛型在实际项目中的运用

代码片段1:


代码片段2:


代码片段3:


原创粉丝点击