前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >List的四张面孔(泛型)

List的四张面孔(泛型)

作者头像
java达人
发布2018-01-31 18:07:52
5420
发布2018-01-31 18:07:52
举报
文章被收录于专栏:java达人java达人

编程的时候,能在编译时发现并修改错误最好,等上线运行时报错才解决,则属于生产事故,且找到bug的位置需要花费更多的时间和精力。泛型是java1.5以后出的内容,运用泛型,指定集合中的对象类型,你可以在编译时发现类型不匹配的错误,并且取数据时不需要手动强转类型。

我们最常用的集合类之一便是List,假如我们想让这个List只放Integer类型的元素,可以这样创建集合类:

List<Integer> list = new ArrayList<Integer>;

List.add(new Integer(88));

一般的编程工作中对泛型的运用也就仅此而已,但你若想让你的程序更加安全,更加清爽,必须深入理解知识点,挖掘泛型的潜能。在此我们就循序渐进,来了解下List在运行泛型后需要注意的四张面孔

List<Object>

List

List<?>

List<E>

以下是示例代码,相关解释都在注释里面,大家可以把代码粘贴到eclipse上对照查看,效果更好

代码语言:js
复制
import java.util.ArrayList;
import java.util.List;
public class KnowGeneric {
 private static void normAdd(List<Object> list, Object o) {
 list.add(o);
 }
 private static void rawAdd(List list, Object o) {
 list.add(o);
 }
 private static <E> void wildCardQueryAdd(List<?> list, Object o) {
 if (list.contains(o)) {
   System.out.println("contain");
  } else {
   System.out.println("not contain");
  }
 /*
   * list集合不能添加除null以外的任何元素。 
compile error The method add(capture#1-of ?) in the
   * type List<capture#1-of ?> is not applicable for the arguments (Object)
   */
 list.add(o);
 list.add(null);
 }
 private static <E> void geneAdd(List<E> list, E e) {
 list.add(e);
 }
 public static void main(String[] args) {
  List<Integer> numList = new ArrayList<Integer>();
  List<Object> objList = new ArrayList<Object>();
 // 编译通过
 normAdd(objList, new Object());
 // normAdd
 /*
   * normAdd中定义的方法参数是List<Object>类型,rawAdd中的是List原生类型,而List<Integer>是List的子类型,
   * 却不是List<Object>的子类型,因此报如下编译错误 
 编译错误 The method normAdd(List<Object>, Object)
   * in the type Know is not applicable for the arguments (List<Integer>,
   * Integer)
   */
 normAdd(numList, new Integer(88));
 // rawAdd
 numList.clear();
 objList.clear();
 rawAdd(objList, new Object());
 /*
   * 方法声明参数类型为原生类型list,元素类型信息被抹去,以下代码虽然编译通过,
   * 运行时却会报ClassCastException错误,所以尽量不要使用list原生类型,java保留原生类型主要是为了兼容1.5以前的代码。
   * Exception in thread "main" java.lang.ClassCastException: java.lang.String
   * cannot be cast to java.lang.Integer
   */
 rawAdd(numList, "str");
  Integer num = numList.get(0);
 // geneAdd
 numList.clear();
 objList.clear();
 geneAdd(numList, new Integer(88));
 /*
   * 定义使用了泛型方法,编译时进行类型检查,添加字符串时会报编译错误。 compile error The method geneAdd(List<E>,
   * E) in the type Know is not applicable for the arguments (List<Integer>,
   * String)
   */
 geneAdd(numList, "33");
 // wildCardQueryAdd
 numList.clear();
 objList.clear();
 /*
   * 前面讲了不要使用list原生类型,如果集合中元素类型未知或者无关紧要,则可以使用无界通配符List<?>,
     不像 normAdd(numList,new Integer(88));下面这段代码可以编译通过的,但是方法体中,numList集合不能添加除null以外的任何元素。
   */
 wildCardQueryAdd(numList, new Integer(33));
 }
}

也许大家有个疑问normAdd方法只能传List<Object>类型的参数,rawAdd方法又不建议使用,而wildCardQueryAdd方法中不能对集合添加除null以外的元素(使用场景有限),那该怎么办,上面代码中的泛型方法geneAdd是一个解决途径,另外就是有界通配符了,我们下回再讲。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-05-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 java达人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档