`
zybing
  • 浏览: 456945 次
  • 性别: 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语言中的一种机制,它允许在定义类、接口时指定类型形参,这个类型形参将在声明变量、创建对象时确定。泛型的引入解决了Java集合的缺陷,即集合会“忘记”对象的类型,导致...

    十三、集合进阶 泛型的继承和通配符

    3. **类型擦除**:Java的泛型是通过类型擦除来实现的,这意味着在运行时,所有的泛型信息都会被擦除,所有的泛型类型都退化为Object。因此,泛型的主要作用是在编译时提供类型检查,而不是在运行时提供类型信息。 4...

    泛型类型转换Demo

    这样,可以根据枚举值来确定应该使用的泛型类型。 6. **集合的泛型操作**: 在Java中,集合框架的泛型操作包括添加、删除、查找和遍历元素。这些操作在运行时会进行类型检查,确保插入的元素与集合的泛型类型匹配...

    Java 泛型最全指南(定义和使用+继承泛型类/实现泛型接口+泛型的边界+通配符+类型擦除)

    参数化类型是指在使用泛型类时指定了具体的类型。例如,`List&lt;String&gt;` 是一个参数化类型,`List` 是泛型类,`String` 是具体的类型。 4. 原始类型 原始类型是指参数化类型的泛型类的 Class。例如,`List` 的原始...

    泛型&通配符常见面试题总结

    2. 泛型的边界:`&lt;T extends SomeClass&gt;` 定义泛型类型T必须是SomeClass或其子类。 3. 野指泛型(Raw Types):未指定类型参数的泛型类,如ArrayList。虽然可用,但不推荐,因为它会降低类型安全性。 4. 增强for...

    Java泛型类型擦除后的补偿

    本文将深入探讨Java泛型类型擦除的概念,并介绍在类型擦除后,为了保持泛型的安全性和便利性,Java设计者所采取的一些补偿机制。 1. **类型擦除**: - 在编译期间,所有的泛型类型信息都会被替换为它们的实际类型...

    Java 泛型总结(三):通配符的使用

    上边界限定通配符使用 &lt;? extends Fruit&gt; 形式,表示该泛型容器只能包含 Fruit 或者其子类型。下边界限定通配符使用 &lt;? super Fruit&gt; 形式,表示该泛型容器只能包含 Fruit 或者其父类型。 在使用通配符时,我们需要...

    JDK 5.0中的泛型类型学习.docx

    总的来说,JDK 5.0中的泛型类型为Java提供了类型安全的容器,但其工作原理和限制(如类型擦除、非协变性以及构造延迟)需要开发者充分理解和掌握,以便正确、安全地使用泛型。在实际编程中,理解这些概念可以帮助...

    Java中泛型通配符的使用方法示例

    Java 中泛型通配符的使用方法示例主要介绍了 Java 中泛型通配符的使用方法,结合实例形式分析了 Java 中泛型通配符的功能、语法及在泛型类创建泛型对象中的使用方法。以下是 Java 中泛型通配符的使用方法示例的知识...

    Java 泛型通配符的一个实例

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

    Java1.5泛型指南中文版(Java1.5Gene....pdf

    通配符是泛型类型参数的占位符,用于表示可变的类型参数。例如,`List&lt;? extends Number&gt;` 表示一个可以存储 Number 或其子类的列表。通配符可以分为bounded wildcards 和 unbounded wildcards 两种。 5. 泛型方法 ...

    泛型需要注意的问题.pdf

    super 类型`)是泛型使用中的一部分,限定通配符用于声明泛型类型的上限或下限,从而使得代码的通用性更强,同时也能够提供一定的类型安全保证。例如,`List&lt;? extends Number&gt;`能够接收任何`Number`及其子类的`...

    实例189 - 使用通配符增强泛型

    实例189 - 使用通配符增强泛型,着重探讨了如何通过通配符来提升泛型的灵活性和可复用性。这个主题与源码理解和工具应用紧密相关。 首先,让我们理解什么是通配符。在Java的泛型中,通配符(Wildcard)是问号(?)...

    java 通配符使用示例

    在本示例中,我们将深入探讨Java中的通配符使用,以及它们如何增强代码的可复用性和可读性。 首先,Java中的通配符主要有两种类型:无界通配符(?)和有界通配符(? extends T 或 ? super T)。无界通配符表示可以...

    java泛型常用通配符实例解析

    限定通配符是指在泛型中使用extends关键字来限定类型的通配符,语法格式为`&lt;? extends E&gt;`,其中E是某个类型的名称。例如,在上述代码中,我们可以使用`Gys&lt;? extends T&gt;`来限定addAll方法的参数类型,表示该方法...

    Java泛型类型通配符和C#对比分析

    在C#中,我们可以使用`where`关键字来指定泛型类型的约束,如`class`约束表示类型必须是引用类型,`struct`约束表示类型必须是值类型。此外,C#还可以指定接口约束,如`IMyInterface`,以及基类约束,如`Dictionary,...

    Java1.5泛型指南中文版

    Class Literals as Run-time Type Tokens 是一种利用类字面量(Class literals)作为运行时类型标识符的技术,常用于反射中获取泛型类型信息。 通配符匹配(wildcard capture)是指编译器会为每个通配符创建一个...

    Java中泛型的各种使用

    下面将详细讨论Java中泛型的使用及相关知识点。 1. 泛型的基本概念 泛型是Java SE 5.0引入的新特性,它允许在类、接口和方法中使用类型参数。类型参数类似于函数参数,但它们代表的是类型而不是值。例如,`List&lt;T&gt;`...

    JAVA泛型笔记.pdf

    在上面的例子中,泛型类型参数 `&lt;T&gt;` 被约束为 `Number` 或者其子类。 泛型的通配符 泛型的通配符是指 `?` 符号,它可以用来表示未知的类型参数。例如: ```java public class Box&lt;T&gt; { private T t; public ...

Global site tag (gtag.js) - Google Analytics