现在的位置: 首页 > 综合 > 正文

疯狂JAVA讲义—第八章:泛型

2013年10月13日 ⁄ 综合 ⁄ 共 2899字 ⁄ 字号 评论关闭

泛型主要用在上一章的集合上的,为了能在编译时就发现错误。

为了大家的理解,先举个反例,(这个例子将发生ClassCastException,不要再评论说这个例子为什么错)

  1. public class ListErr
  2. {
  3.     public static void main(String[] args) 
  4.     {
  5.         //创建一个只想保存字符串的List集合
  6.         List strList = new ArrayList();
  7.         strList.add("Struts2权威指南");
  8.         strList.add("基于J2EE的Ajax宝典");
  9.         strList.add("轻量级J2EE企业应用实战");
  10.         //”不小心“把一个Integer对象”丢进"了集合
  11.         strList.add(5);
  12.         for (int i = 0; i < strList.size() ; i++ )
  13.         {
  14.             //因为List里取出的全部是Object,所以必须强制类型转换
  15.             //最后一个元素将出现ClassCastException异常
  16.             String str = (String)strList.get(i);
  17.         }
  18.     }
  19. }

为了解决这个问题,在1.5前都采用,创建个List对象的方法,但每遇到个集合都要建个对象,eg

  1. class StrList
  2. {
  3.     private List strList = new ArrayList();
  4.     //定义StrList的add方法
  5.     public boolean add(String ele)
  6.     {
  7.         return strList.add(ele);
  8.     }
  9.     //重写get方法,将get方法的返回值类型改为String类型
  10.     public String get(int index)
  11.     {
  12.         return (String)strList.get(index);
  13.     }
  14.     public int size()
  15.     {
  16.         return strList.size();
  17.     }
  18. }
  19. public class CheckType
  20. {
  21.     public static void main(String[] args) 
  22.     {
  23.         //创建一个只想保存字符串的List集合
  24.         StrList strList = new StrList();
  25.         strList.add("Struts2权威指南");
  26.         strList.add("基于J2EE的Ajax宝典");
  27.         strList.add("轻量级J2EE企业应用实战");
  28.         //下面语句不能把Integer对象“丢进”集合中,将引起编译异常
  29.         strList.add(5);
  30.         System.out.println(strList);
  31.         for (int i = 0; i < strList.size() ; i++ )
  32.         {
  33.             //因为StrList里元素的类型就是String类型,所以无需强制类型转换
  34.             String str = strList.get(i);
  35.         }
  36.     }
  37. }

有了泛型就方便了,eg

  1. public class GenericList
  2. {
  3.     public static void main(String[] args) 
  4.     {
  5.         //创建一个只想保存字符串的List集合
  6.         List<String> strList = new ArrayList<String>();
  7.         strList.add("Struts2权威指南");
  8.         strList.add("基于J2EE的Ajax宝典");
  9.         strList.add("轻量级J2EE企业应用实战");
  10.         //下面代码将引起编译错误
  11.         strList.add(5);
  12.         for (int i = 0; i < strList.size() ; i++ )
  13.         {
  14.             //下面代码无需强制类型转换
  15.             String str = strList.get(i);
  16.         }
  17.     }
  18. }

使用时注意:List<String>不是List<Object>子类

特殊的泛型(带类型通配符和类型上限),eg

  1. public class Apple<T extends Number>
  2. {
  3.     T col;
  4.     
  5.     public static void main(String[] args)
  6.     {
  7.         Apple<Integer> ai = new Apple<Integer>();
  8.         Apple<Double> ad = new Apple<Double>();
  9.         //下面代码将引起编译异常
  10.         //因为String类型传给T形参,但String不是Number的子类型。
  11.         Apple<String> as = new Apple<String>();
  12.         
  13.     }
  14. }

java泛型不支持泛型数组(List<String> aa=new ArrayList<String>[10];),因为java泛型的设计原则是没有unchecked警告就没有ClassCastExcepiton. 我建议大家遇到集合数组等的时候,自己来检验数据的类型,eg

  1. public class test {
  2.     public static void main(String[] args) {
  3.         ArrayList[] aa = new ArrayList[10];
  4.         List<Integer> li = new ArrayList<Integer>();
  5.         li.add(3);
  6.         ((Object[]) aa)[1] = li;
  7.         Object target = aa[1].get(0);
  8.         if (target instanceof Integer) {
  9.             Integer s = (Integer) target;
  10.             System.out.println(s);
  11.         }
  12.     }
  13. }

由于java的泛型只是编译时做下检验,大家不要想的过于强大,他的最大作用只是增强代码的可读性,别的方面也没见多大的作用。

 

 

 

抱歉!评论已关闭.