`
zybing
  • 浏览: 446498 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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

 
阅读更多

最近碰到一个泛型的问题, 就在网上找技术贴, 挖坟挖出个08年的技术贴, 解决了问题

 

来源: http://webservices.ctocio.com.cn/wsjavtec/128/8571628_1.shtml

 

 

 

 

原文:

  在java语言中,我们通俗讲一个类是另一个类的子类型,是通过使用extends关键字去继承某一个类或者使用implements关键字去实现某些接口。

  我们不妨试想想,若果List< Integer>类型的变量可以成功赋值给List< Number>类型的变量,会出现什么情况?我们可能在程序的某个位置添加一个double类型的元素进去numList中,而实质上在 numList中其它元素都是Integer的类型的元素,这样就违背了泛型的初衷了。

  有时,我们确实希望将形如List< Integer>的List对象赋给List< Number>的变量,这时就要使用extends关键字的通配符。

  (2) 使用extends关键字的通配符

  Example2.3

  List< Integer> intList = new ArrayList< Integer>();

  List< ? extends Number> numList = intList();

  …

  numList.add(1.35); //compile error (can’t do that)

  从Example2.3看到numList这个变量,我们可以将类型参数为Number及其Number子类的List赋给它。

  记住一条规则如果你使用了”? extends T”,一般情况下,你不能往该数据结构中put元素,而你可以做的就是get元素。

  如果要往内put元素,就需要使用下面提到的super关键字的通配符。

  (3) 使用super关键字的通配符

  Example2.4

  List< Integer> intList = new ArrayList< Integer();

  List< ? super Integer> numList = intList;

  numList.add(3); //can put integer or null

  在example2.4我们可以看到< ? super Integer>的意思为,我们可以将类型参数为Integer或Integer超类的List赋给numList变量,并且可以put元素到列表 中(注意:在该例子中put进的元素只能为Integer或null类型)。

  一条比较通用的规则:如果要往List中put元素则用< ? super T>,如果要从List中get元素则用< ? extends T>,如果既要get又要put则不使用通配符。

 

 

实践下来, 用 < ? super T > 既可以add, 也可以get元素, 就是用不了 for (T t : tlist) 不过可以用 iterator来代替

 

/**
*  执行环境 Eclipse3.5  JDK1.5 
*/

class A {
   protected int a;
   
   public A(int value) { a = value; }

 public int get(){return a; }
}

class AA extends A{
   public AA(int value) { super(value); }
}

public static main(String[] argc){
   List< ? super A > alist = new ArrayList<A>();

    // 以下3种类型,都可以add进list
    A a  = new A(1); 
    alist.add(a);

    A a1 = new AA(2); 
    alist.add(a1);

    AA a2 = new AA(3);
   alist.add(a2);

   Iterator  aa = alist.iterator();
   while ( aa.hasnext()){
        A  theA = (A)aa.next();
       System.out.println(theA.get() );  // 输出1/2/3 
 }

    // 下面代码编译报错
    for( A theA : alist) {
   }

}
 

 

 

分享到:
评论

相关推荐

    Java 泛型通配符的一个实例

    * 一个参数通配符的实例 * 说明:对一个包含了数值元素的集合进行汇总运算。在这种情况下,用户并不关心 * 集合中的每一个对象... * 方法声明了一个参数变量values是List类型,该集合中的元素必须是Number的子类对象

    java泛型总结.docx

    泛型类型:定义泛型类型时,使用尖括号,并在尖括号中指定类型参数。例如,List表示一个字符串类型的列表。 泛型方法:定义泛型方法时,在方法名后面使用尖括号,并在尖括号中指定类型参数。例如,public static &lt;T&gt;...

    Java 基础泛型.pdf

    2. 类型擦除:Java泛型在编译时实现类型安全检查,但在运行时会将泛型类型的信息擦除,转换为原始类型。这是为了保持与Java早期版本的兼容性,同时减少运行时的开销。例如,List在运行时会被擦除为List。 3. 上限和...

    \java超强笔记(超级经典)

    类的静态变量不能声明为类的泛型类型 public class GenClass&lt;T&gt; { private static T t; //编译错误 } 静态方法可以是泛型方法(在修饰符和返回值之间写泛型),但是不可以使用类的泛型。 ...

    Java 基础核心总结 +经典算法大全.rar

    泛型通配符 反射 Class 类Field 类Method 类ClassLoader 类 枚举 枚举特性 枚举和普通类-样枚举神秘之处 枚举类 I/O File 类 基础 IO 类和相关方法InputStream OutputStream Reader 类Writer 类 InputStream ...

    疯狂JAVA讲义

    8.4.2 泛型方法和类型通配符的区别 306 8.4.3 设定通配符的下限 307 8.4.4 泛型方法与方法重载 309 8.5 擦除和转换 310 8.6 泛型与数组 311 8.7 本章小结 313 第9章 与运行环境交互 314 9.1 与用户互动 315 ...

    Java开发技术大全 电子版

    10.3带两个类型参数的泛型类308 10.4有界类型309 10.5通配符参数311 10.6泛型方法313 10.7泛型接口315 10.8泛型类的继承317 10.8.1以泛型类为父类317 10.8.2以非泛型类为父类319 10.8.3运行时类型识别320 ...

    快学 scala 中文版 带完整目录

    18.12 类型通配符 308 练习 309 第19章 高级类型 L2 313 19.1 单例类型 313 19.2 类型投影 315 19.3 路径 316 19.4 类型别名 317 19.5 结构类型 318 19.6 复合类型 319 19.7 中置类型 320 19.8 存在类型 ...

    Java开发技术大全(500个源代码).

    代码范例列表 第1章 示例描述:本章演示如何开始使用JDK进行程序的开发。...示例描述:本章学习泛型。 demoBounds.java 演示有界类型 demoForceChange.java 演示强制类型转换 demoGeneric.java ...

    corejava培训文档

    17.1.3. 泛型的通配符"?" 17.1.4. 泛型方法的定义 17.1.5. 泛型类的定义 17.1.6. 泛型与异常 17.1.7. 泛型的一些局限型 17.2. 增强的for循环 17.3. 自动装箱和自动拆箱 17.3.1. 在基本数据类型和封装类之间的...

    java学习笔记 初学者必读

    17.1.3. 泛型的通配符"?" 17-62 17.1.4. 泛型方法的定义 17-63 17.1.5. 泛型类的定义 17-63 17.1.6. 泛型与异常 17-64 17.1.7. 泛型的一些局限型 17-65 17.2. 增强的for循环 17-66 17.3. 自动装箱和自动拆箱 17-69 ...

    corejavaNoteBook

    17.1.3. 泛型的通配符"?" 17-62 17.1.4. 泛型方法的定义 17-63 17.1.5. 泛型类的定义 17-63 17.1.6. 泛型与异常 17-64 17.1.7. 泛型的一些局限型 17-65 17.2. 增强的for循环 17-66 17.3. 自动装箱和自动拆箱 17-69 ...

Global site tag (gtag.js) - Google Analytics