11级_Java_曹建波 09.20 泛型

来源:互联网 发布:淘宝需要开定位吗 编辑:程序博客网 时间:2024/06/05 21:45

泛型

泛型(Generic)—泛形的作用

JDK5以前,对象保存到集合中就会失去其特性,取出时通常要程序员手工进行类型的强制转换,这样不可避免就会引发程序的一些安全性问题。例如:

ArrayList list = new ArrayList();

list.add("abc");

Integer num = (Integer) list.get(0); //运行时会出错,但编码时发现不了

 

list.add(new Random());

list.add(new ArrayList());

for(int i=0;i<list.size();i++){

      (?)list.get(i);         //此处取出来的对象应转换成什么类型

}

JDK5中的泛形允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定性(尤其在大型程序中更为突出)

注意:泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为擦除

泛形的基本术语,以ArrayList<E>为例:<>念着typeof

ArrayList<E>中的E称为类型参数变量

ArrayList<Integer>中的Integer称为实际类型参数

整个称为ArrayList<E>泛型类型

整个ArrayList<Integer>称为参数化的类型ParameterizedType

使用迭代器迭代泛形集合中的元素。

使用增强for循环迭代泛形集合中的元素。

存取HashMap中的元素。

使用泛形时的几个常见问题:

使用泛形时,泛形类型须为引用类型,不能是基本数据类型

ArrayList<String> list = newArrayList<Object>(); //

ArrayList<Object> list = newArrayList<String>(); //

ArrayList<String> list = newArrayList ();              //

ArrayList list = newArrayList<String>();              //

:使用泛型

       * 两边的类型必须一致

             ArrayList<String> list =new ArrayList<String>();

       * 两边只有一边用泛型(为了保持兼容性)

             ArrayList<String> list =new ArrayList ();

             ArrayList list = newArrayList<String>();

自定义泛形——泛型方法

Java程序中的普通方法、构造方法和静态方法中都可以使用泛型。方法使用泛形前,必须对泛形进行声明,语法:<T>T可以是任意字母,但通常必须要大写。<T>通常需放在方法的返回值声明之前。例如:

      publicstatic <T> void method(T t);

注意:

只有对象类型才能作为泛型方法的实际参数。

在泛型中可以同时有多个类型,例如:

             

如果一个类多处都要用到同一个泛型,这时可以把泛形定义在类上(即类级别的泛型),语法格式如下:

      publicclass GenericDao<T> {

             privateT field1;

             publicvoid save(T obj){}

             publicT getId(int id){}

      }

注意

   * 在类级别上定义的泛型,只对类的非静态成员有效

   * 静态方法不能使用类定义的泛形,而应单独定义泛形。

泛型的高级应用——通配符

定义一个方法,接收一个集合,并打印出集合中的所有元素,如下所示:

  void print (Collection<String>c) {

          for (String e : c) {

                System.out.println(e);

          }

问题:该方法只能打印保存了String对象的集合,不能打印其它集合。通配符用于解决此类问题,方法的定义可改写为如下形式:

 void print (Collection<?> c) {   //Collection<?>(发音为:"collection ofunknown")

for (Object e : c) {

      System.out.println(e);

}

}

此种形式下需要注意的是:由于print方法c参数的类型为Collection<?>,即表示一种不确定的类型,因此在方法体内不能调用与类型相关的方法,例如add()方法。

      但可以调用与类型无关的方法,例如size()方法

总结:使用?通配符主要用于引用对象,使用了?通配符,就只能调对象与类型无关的方法,不能调用对象与类型有关的方法。

泛型的高级应用——有限制的通配符

限定通配符的上边界(?的类型必须是Number的子类)

限定通配符总是包括自己。

正确:Vector<?extends Number> x = new Vector<Integer>();

错误:Vector<?extends Number> x = new Vector<String>();

限定通配符的下边界(?的类型必须是Integer的父类)

正确:Vector<?super Integer> x = new Vector<Number>();

错误:Vector<?super Integer> x = new Vector<Byte>();

问题:以下代码行不行?(如果是Byte类型不可以)

public void add(List<? extendsNumber> list){

      list.add(1000);

}

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手劳累过度麻痛怎么办 大人发烧40不退怎么办? 颈椎扯的脑袋疼怎么办 孕妇颈椎痛导致失眠怎么办 做完运动脊椎中间痛怎么办? 阴虛阴虚火旺怎么办 脸一躺下就丑怎么办 身体淤堵的厉害怎么办 怀孕晚期脚肿了怎么办 宝宝感冒咳嗽流鼻涕流泪怎么办 孕晚期睡觉习惯面朝右怎么办 鼻涕一直不停的流怎么办 宝宝一直流清鼻涕怎么办 感冒了眼睛酸胀流泪怎么办 五个月宝宝感冒流鼻涕怎么办 六个月宝宝感冒流鼻涕怎么办 一岁宝宝感冒咳嗽流鼻涕怎么办 七个月宝宝感冒流鼻涕咳嗽怎么办 孩子握笔姿势不正确怎么办 走久了脚底板痛怎么办 不会给宝宝拍嗝怎么办 打了肉毒素淤青怎么办 新生儿一吃母乳就睡觉怎么办 10岁半宝宝缺钾怎么办 宝宝吃不到乳晕怎么办 喂母乳乳头破了怎么办 宝宝吸了乳头痛怎么办 喂母乳奶头很疼怎么办 孩子吸的乳头痛怎么办 新生儿一直睡觉不吸吮怎么办 新生儿光睡觉不吃奶怎么办 婴儿不吸母亲的奶怎么办 肾里有结石一直不掉下来怎么办 宝宝拍不出来嗝怎么办 未满月宝宝溢奶怎么办 吃母乳老是吐奶怎么办 宝宝吃母乳吐奶怎么办 新生儿三天没大便了怎么办 奶水多宝宝呛奶怎么办 婴儿的含乳姿势不正确怎么办 一个月竖着抱了怎么办