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

Java基础 -- 泛型之泛型参数

阅读更多
泛型机制常用的参数有3个:
“?”代表任意类型。如果只指定了<?>,而没有extends,则默认是允许任意类。
extends关键字声明了类型的上界,表示参数化的类型可能是所指定的类型,或者是此类型的子类。
super关键字声明了类型的下界,表示参数化的类型可能是所指定的类型,或者是此类型的父类型,直至Object
前提
Fruit是Apple和Orange的超类。
本章通过java代码逐一分析泛型参数的意义和区别
extends参数:
[java] 
public void extend(List<? extends Fruit> list, Fruit fruit){   
        Fruit now = list.get(0);   
        System.out.println("now==>" + now); 
    //    Apple a = list.get(0);  无法通过编译 
        Object o = list.get(0);  
        System.out.println(o); 
        // list.add(fruit); //这句话无法编译     
        // list.add(new Object());  // 无法通过编译 
        list.add(null);//这句可以编译,因为null没有类型信息   
    }  
在上面的例子中,可以明确从list中取得的记录一定是Fruit,但是无法确定是Apple,list除了传入null外,不能添加其他任何参数;分析原因前先看以下的例子:
[java]
public void testExtendType(){ 
    List<? extends Fruit> list = new ArrayList<Fruit>(); 
    List<? extends Fruit> list2 = new ArrayList<Apple>(); 
    List<? extends Fruit> list3 = new ArrayList<Orange>(); 
    extend(list2, new Apple()); 

从以上代码可以看出:
extends关键字声明了类型的上界,表示参数化的类型可能是所指定的类型,或者是此类型的子类,List<? extends Fruit> 可以指向 ArrayList<Fruit>()、ArrayList<Apple>()、ArrayList<Orange>()等。现在如果传入的参数list为new ArrayList<Apple>(),则此时你向此list中添加
Fruit,则肯定报错。而读取数据时,不管list是什么类型,读取的数据肯定都是Fruit,同时Fruit也是Object。
通过以上的分析,知道直接往继承extends中的列表中添加记录是不行的,那么如何向extends修饰的list中添加记录,可以使用泛型方法来达到目的:
[java] 
public <T extends Fruit> void extendType2(List<T> list, T date){   
        list.add(date);   
    }  
调用示例如下:
[java] 
public void testExtendType2(){   
        List<Apple> list = new ArrayList<Apple>();   
        extendType2(list,new Apple());   
    } 
super参数
super用的不多,只简单介绍一下。
[java] 
public void superType(List<? super Apple> list, Apple apple){   
        Object o = list.get(0); 
        System.out.println(o); 
    //  Apple a = list.get(0); // 不能编译 
         
     // Apple apple = list.get(0); // 不能编译   
        list.add(apple); 
//      list.add( new Object());  // 不能编译 
//      list.add( new Fruit());  // 不能编译 
    }   
在以上代码中,从list中读取的记录无法确定是任何类型(除Object),list除了添加Apple外,不能添加任何类型的对象(包括Object)。分析原因前先看以下代码:
[java] 
public void testSuperType(){   
    List<? super Apple> list = new ArrayList<Apple>();   
    List<? super Apple> list2 = new ArrayList<Fruit>();  
    superType(list2, new Apple());   

super关键字声明了类型的下界,表示参数化的类型是所指定的类型,或者是此类型的父类型,直至Object。List<? super Apple > 可以引用  List<Apple>,也可以引用 List<Fruit>,所以无法保证list中都是Apple,但是可以保证,所有list引用的都是Apple的父类,所有向此列表中添加Apple是没有问题的,而很显然你向List<Fruit>、List<Apple>中添加Object、Fruit对象,肯定失败,只能够添加Apple。
?参数
“?”代表任意类型。?可以看做 ? extends Object 的缩写。
[java]
public void wideCardType(List<?> list, Fruit fruit ){ 
    Object o = list.get(0); 
    System.out.println(list.get(0)); 
    //  list.add(fruit);  // 不能编译 
    //  list.add(new Object()); // 不能被编译 

[java] 
public void testWideCardType(){ 
        /**
         * ? 可以看做 ? extends Object 的简化版
         */ 
        List<?> list = new ArrayList<Fruit>(); 
        List<?> list2 = new ArrayList<Apple>(); 
        List<?> list3 = new ArrayList<Object>(); 
         
        wideCardType(list,new Fruit()); 
    } 
List<? super Object> 可以引用  List<任何类型>,而Object是所有的对象的祖先,此list只能添加Object类型对象。
extends和super意义记忆的技巧
? extends A: ?继承A,?是A的子类,或者?是A本身
? super B:    ?是B的父类,或者?是B本身
分享到:
评论

相关推荐

    fantj2016#java-reader#10. Java反射---泛型1

    而不是创建一个Object列表,你可以参数化java.util.List来创建一个String String列表,如下所示:当通过反射在运行时检查可参数化类型本

    Generic_2(泛型类-泛型方法-泛型接口-泛型限定(上限)

    泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是...

    java中的泛型-详细

     1、Java泛型  其实Java的泛型就是创建一个用类型作为参数的类。就象我们写类的方法一样,方法是这样的method(String str1,String str2 ),方法中参数str1、str2的值是可变的。而泛型也是一样的,这样写class Java...

    day017-Map和泛型 代码和笔记.rar

    day017-Map和泛型 代码...3. 泛型:就是一个占位符号而已,在设计类的时候,占用位置就是在设计类(接口等)的时候,没有给规定具体是什么类型的参数,在实例化或调用的时候再传入具体的类型,告诉编译器这是什么类型。

    Java如何获取泛型类型

    Java 运行时如何获取泛型参数的类型 Java类型Type 之 ParameterizedType,GenericArrayType,TypeVariabl,WildcardType 从实现的接口获取泛型参数 定义一个泛型父类: public interface SuperClass { String ...

    java 带两个类型参数的泛型

    java 带两个类型参数的泛型 java 带两个类型参数的泛型

    JAVA-泛型基本讲解

    1、Java泛型是J2 SE1.5中引入的一个新特性,其本质是参数化类型,也就是说所操作的数据类型被指定为一个参数(type parameter)这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。...

    java 泛型类的类型识别示例

    java 泛型类的类型识别示例 java 泛型类的类型识别示例 java 泛型类的类型识别示例

    Generic_3(泛型限定(下限)-泛型限定(上限的体现)-泛型限定(下限的体现)-泛型限定(通配符的体现)-集合查阅的技巧)

    泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是...

    JAVA-泛型的使用

    ( 例如,a为{2,1,2,2}, b为{1,0,0,1} ),编写带有泛型传递参数的程序求: 统计a中包含多少种不同的值。(如上述例子中,a中包含2和1两种不同的数)(求秩) a中每一个数与b中同一位置的数称为对应关系,统计a中每种数...

    Java 基础泛型.pdf

    Java泛型的核心思想是类型参数化,即在类、接口或方法的定义中使用类型参数来代替具体的类型,这些类型参数在实例化时被具体类型替换,从而实现了通用性和类型安全。 主要特性包括 1. 类型参数:在类、接口或方法的...

    java基础学习笔记之泛型

    所谓泛型,就是变量类型的参数化。泛型是JDK1.5中一个最重要的特征。通过引入泛型,我们将获得编译时类型的安全和运行时更小的抛出ClassCastException的可能。在JDK1.5中,你可以声明一个集合将接收/返回的对象的...

    深入Java泛型

    详细介绍JAVA的泛型,泛型的类型参数只能是类类型(包括自定义类)

    Java语言 泛型讲解案例代码 (泛型类、泛型接口、泛型方法、无界及上下限通配符、泛型对协变和逆变的支持、类型擦除 ...)

    学习和理解Java泛型的基本概念和语法; 实际项目中需要使用泛型来增加类型安全性和重用性的开发任务。 目标: 本代码资源的目标是帮助读者理解泛型的用法和优势,并通过实际的示例代码加深对泛型的掌握。读者可以...

    java 用泛型参数类型构造数组详解及实例

    主要介绍了java 用泛型参数类型构造数组详解及实例的相关资料,需要的朋友可以参考下

    使用泛型的方法.java

    泛型是程序设计语言的一种特性。允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明。各种程序设计语言和其...泛型类是引用类型,是堆对象,主要是引入了类型参数这个概念。

    whlmpower#JavaNote#获取泛型参数的实际类型及反序列化1

    获取泛型参数的实际类型}//获取此类的父类的第一个泛型参数的实际类型对应于实际的类型PayResultHandler,其父类HPWallletCallBackH

    JAVA第八章 泛型.pptx

    了解泛型,能够说出泛型的作用和优点 掌握泛型类,能够独立定义和使用泛型类 掌握泛型接口,能够独立定义和使用泛型接口 掌握泛型方法,能够独立定义并使用...01泛型基础 02泛型类 03泛型接口 04泛型方法 05类型通配符

    java_泛型类相关介绍.docjava_泛型类相关介绍.doc

    泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。  Java语言引入泛型的好处是...

    java-generics-collections:Java核心中的泛型和集合

    泛型格式化参数化数据类型,以便我们可以将类,接口或方法用于许多不同的数据类型。 集合只是具有相同数据类型的对象的集合,具体取决于结构,存储和安排这些对象的方式,我们将它们分为以下几类: 大批 收藏 ...

Global site tag (gtag.js) - Google Analytics