泛型类型的子类及通配符的使用

本文探讨了Java泛型中的子类替换原则、使用extends与super关键字的通配符。解释了如何正确地使用泛型确保类型安全,避免不当操作。
导读:
  本文讲述以下几个方面的内容,试图说明泛型类型的子类及通配符的使用。
  [bitsCN.Com]
  (1) 子类及替换原则;
  www_bitscn_com中国.网管联盟
  (2) 使用extends关键字的通配符;
  [bitsCN.Com]
  (3) 使用super关键字的通配符; 中国_网管联盟bitsCN.com
  (1) 子类及替换原则
  bitsCN~com
  在java语言中,我们通俗讲一个类是另一个类的子类型,是通过使用extends关键字去继承某一个类或者使用implements关键字去实现某些接口。这样我们在编程时就可以面向接口或基类进行编程,如: bbs.bitsCN.com
  Number num1 = new Integer(1); DL@bitsCN_com网管软件下载
  Number num2 = new Double(2.1d); [bitsCN.Com]
  这个就是所谓的替换原则,替换原则的定义是:
  [bitsCN.Com]
  Substitution Principle: a variable of a given type may be assigned a value of any subtype of that type, and a method with a parameter of a given type may be invoked with an argument of any subtype of that type. bitsCN#com中国网管联盟
  大概的意思是说某种类型的变量可以被该类型的任何子类所赋值,一个方法中的参数也可以被该参数的任何子类进行调用。 [bitsCN.Com]
  现在我们再来看看泛型中替换原则的适用性: bbs.bitsCN.com
  Example2.1 bbs.bitsCN.com中国网管论坛
  List listNums = new ArrayList ();
  BBS.bitsCN.com网管论坛
  nums.add(10); bitsCN#com中国网管联盟
  nums.add(8.88);
  www_bitscn_com中国.网管联盟
  在example2.1 中,可以看出替换原则被很好地应用在这里,ArrayList是List的子类,我们提供给listNums变量的类型参数为Number,往 listNums中添加元素时,10被封箱为Integer类型,而Integer是Number的子类,第三行的情况类似。 bbs.bitsCN.com中国网管论坛
  Example2.2
  DL@bitsCN_com网管软件下载
  List intList = new ArrayList (); bitsCN#com中国网管联盟
  List numList = intList; //compile error bitsCN.nET*中国网管博客
  … 中国_网管联盟bitsCN.com
  numList.add(1.35); // can‘t do that www@bitscn@com
  根据替换原则,我们会很容易想到,既然Integer是Number的子类,则我们应该可以将List 的变量赋给 List 的变量,但从实际情况表明,List 并不是List 的子类。 www_bitscn_com中国.网管联盟
  我们不妨试想想,若果List 类型的变量可以成功赋值给List 类型的变量,会出现什么情况?我们可能在程序的某个位置添加一个double类型的元素进去numList中,而实质上在numList中其它元素都是Integer 的类型的元素,这样就违背了泛型的初衷了。
  bbs.bitsCN.com
  有时,我们确实希望将形如List 的List对象赋给List 的变量,这时就要使用extends关键字的通配符。
  bbs.bitsCN.com
  (2) 使用extends关键字的通配符 BBS.bitsCN.com网管论坛
  Example2.3
  BBS.bitsCN.com网管论坛
  List intList = new ArrayList (); bbs.bitsCN.com
  List<? extends Number> numList = intList();
  bitsCN.nET*中国网管博客
  …
  bbs.bitsCN.com
  numList.add(1.35); //compile error (can‘t do that)
  [bitsCN_com]
  从Example2.3看到numList这个变量,我们可以将类型参数为Number及其Number子类的List赋给它。 bitsCN#com中国网管联盟
  记住一条规则如果你使用了“? extends T”,一般情况下,你不能往该数据结构中put元素,而你可以做的就是get元素。
  bitsCN~com
  如果要往内put元素,就需要使用下面提到的super关键字的通配符。 BBS.bitsCN.com网管论坛
  (3) 使用super关键字的通配符 [bitsCN.Com]
  Example2.4
  bbs.bitsCN.com中国网管论坛
  List intList = new ArrayList
  bbs.bitsCN.com中国网管论坛
  List<? super Integer> numList = intList; BBS.bitsCN.com网管论坛
  numList.add(3); //can put integer or null
  [bitsCN.Com]
  在example2.4 我们可以看到<? super Integer>的意思为,我们可以将类型参数为Integer或Integer超类的List赋给 numList变量,并且可以put元素到列表中(注意:在该例子中put进的元素只能为Integer或null类型)。
  bitsCN~com
  一条比较通用的规则:如果要往List中put元素则用<? super T>,如果要从List中get元素则用<? extends T>,如果既要get又要put则不使用通配符。

本文转自
http://www.bitscn.com/java/advanceprogram/200709/110429.html
的产生条件 是为了解决在编译期间无法确定类型而引入的,其产生条件包括: 1. 在代码中需要使用类型,但是这个类型的具体类型在编译期间是不确定的; 2. 在代码中需要对类型进行操作,比如调用其方法或者获取其属性值。 的概念 是指在编写代码时,不需要指定数据类型,而是在使用时再指定具体的数据类型。这样就可以提高代码的复用性和灵活性。 类是指使用定义的类,其中参数可以用在类的成员变量、成员方法、构造方法中。 类派生类 类派生类是指使用定义的类的子类,其中子类可以继续使用父类中定义的类型。 带子类子类是指在继承类时,子类也要使用类型。 不带子类 不带子类是指在继承类时,子类使用类型接口 接口是指使用定义的接口,其中参数可以用在接口的方法中。 方法 方法是指使用定义的方法,其中参数可以用在方法的参数列表、返回值、方法体中。 类型通配符 类型通配符是指在定义使用的一种特殊符号,用于表示不确定的类型。 引出类型通配符 类型通配符可以用于引出类型参数的上限或者下限。 类型通配符的上限 类型通配符的上限是指使用 extends 关键字限制类型参数的范围,表示类型参数必须是某个类型子类或者实现类。 类型通配符的下限 类型通配符的下限是指使用 super 关键字限制类型参数的范围,表示类型参数必须是某个类型的父类或者超类。 类型擦除 类型擦除是指在编译期间,将类型参数替换为其上限或者 Object 类型的过程。 无限制类型的擦除 无限制类型的擦除是指在类型参数没有明确指定上限或者下限时,将其擦除为 Object 类型。 有限制类型擦除 有限制类型擦除是指在类型参数有明确指定上限或者下限时,将其擦除为上限或者下限。 擦除方法中类型定义的参数 在方法中,如果定义了类型参数,则在编译期间也会进行类型擦除。 桥接方法 在类或者接口中,如果有方法,则在编译期间会自动生成桥接方法来确保类型安全。 数组 数组是指使用定义的数组,其中数组元素的类型类型参数。 与反射 与反射的结合可以实现动态创建类型对象、获取类型信息等功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值