`
weitao1026
  • 浏览: 1047681 次
  • 性别: 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列表,如下所示:当通过反射在运行时检查可参数化类型本

    JAVA-泛型课件-泛型课件

    泛型为Java编程带来了类型安全和代码重用的优势,通过参数化类型的概念,允许开发者编写更通用、更健壮的代码。它减少了类型转换错误,并通过编译时的类型检查避免了运行时的异常。泛型的引入使Java集合框架的使用...

    黑马程序员----泛型与反射的小运用

    由于Java的早期版本不支持泛型,因此在编译时,所有的类型参数都会被替换为它们的边界类型或者Object。这就是为什么我们可以在运行时将任何对象添加到`List&lt;Object&gt;`中,尽管在编译时它可能被声明为`List&lt;String&gt;`。...

    黑马程序员----泛型学习注意点

    在Java编程语言中,泛型(Generic)是一个强大的特性,它允许我们在编译时检查类型安全,并且可以消除运行时的类型转换。黑马程序员提供的这篇关于泛型的学习注意点,结合了源码分析和工具应用,旨在帮助开发者深入...

    大学课程讲义-Java基础-泛型.docx

    Java泛型还支持类型参数的边界,如`? extends Number`,这意味着可以接受任何`Number`的子类。通配符`?`允许在不关心具体类型时,对泛型进行更灵活的操作。 6. **野蛮类型(Raw Types)** 在不指定类型参数的情况...

    很好的Java泛型的总结

    Java泛型机制详解 Java泛型是Java语言中的一种机制,用于在编译期检查类型安全。Java泛型的出现解决了Java早期版本中类型安全检查的缺陷。Java泛型的好处是可以在编译期检查类型安全,避免了运行时的...

    java--泛型编程

    在编译期间,由于Java的类型擦除,泛型信息会被删除,用实际类型替换类型参数,确保在运行时的兼容性。 类型参数有一些限制,它们只能代表引用类型,不能是基本类型如`int`、`double`等。另外,类型参数在整个方法...

    8-java进阶-泛型1

    泛型是Java编程中的一个重要概念,它提供了一种在编译时期检查类型安全性的机制,同时也减少了强制类型转换的需要。泛型主要应用于类、接口和方法中,用来限制可以存储或处理的数据类型。 1. **泛型的意义**: - ...

    无涯教程(LearnFk)-Java-泛型教程离线版.pdf

    Java泛型可以在类、接口、方法声明中使用,它通过使用类型参数来实现。类型参数可以用一个或多个字母来表示,例如T、E、K和V等。 泛型类声明与非泛型类类似,但泛型类在类名后面会有一个类型参数部分,这使得泛型类...

    Java泛型研究.pdf

    Java泛型研究 Java泛型是Java语言中的一种重要机制,自从Java 1.5版本引入泛型以来,Java开发者可以更方便地编写类型安全的代码。泛型的引入解决了Java早期版本中类型不安全的问题,提高了Java语言的开发效率和安全...

    JAVA设计模式--程序设计--反射--注解--泛型

    泛型是Java 5引入的新特性,它允许在类、接口和方法中使用类型参数,增强了类型安全性和代码重用。泛型可以避免类型转换的麻烦,防止在集合操作中插入不兼容的对象,同时在编译时就能捕获潜在的类型错误。例如,...

    关于java基础的泛型的练习

    Java泛型是Java SE 5.0引入的一个重要特性,它极大地增强了代码的类型安全性和可读性。泛型在编程中的应用广泛,特别是在集合框架中,使得我们可以在编译时就检查类型,避免了不必要的类型转换,并且提高了代码的...

    java泛型技术之发展

    - **类型擦除**:Java泛型采用了类型擦除的策略,这意味着在编译期间,泛型信息会被删除,只留下原始的无参数类型,这解决了与Java的向下兼容问题。 - **JDK 5.0引入**:Java 5.0正式引入泛型,使得在编译时期就能...

    Java-Java反射与泛型教程

    Java泛型是自Java 5引入的一种类型安全机制,它允许在编译时检查类型,从而避免了类型转换异常。泛型主要应用于类、接口和方法。 1. **泛型类**: 定义泛型类时,可以使用尖括号来声明类型参数,如`class Container...

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

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

    Java如何获取泛型类型

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

    Java泛型_Java中的泛型结构_

    Java泛型是Java编程语言中一个强大的特性,它允许在定义类、接口和方法时使用类型参数,从而实现参数化类型。泛型的主要目标是提高代码的类型安全性和重用性,减少类型转换的麻烦,并在编译时捕获可能的类型错误。...

Global site tag (gtag.js) - Google Analytics