• Java 泛型(一)作用和使用


    泛型的使用 : https://www.cnblogs.com/jpfss/p/9928747.html

      在没有使用泛型的情况下,如果要实现参数“任意化”,通常会定义成Object类型来接受,然后强制类型转换使用;

      而强制类型转换有明显的缺点,就是必须要知道实际参数的具体类型的情况才可以进行转换,同时在强制转换的过程中,编译器不会报错提示的,只有在运行阶段才会出现异常,一定程度上存在安全隐患。

      泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数的方式传递,类似于方法中的变量参数。可以用在类、接口、方法的创建中,分别简称为泛型类、泛型接口、泛型方法。

    一、泛型作用

      

      为了解决Java容器无法记忆元素类型的问题;

      在早期,如果将容器的元素类型设置为 Object 类,虽然什么类都能放进去,但是有以下问题。  

      a.取出元素的时候必须进行强制类型转换(尽管集合在运行时里面元素的“运行时类型”不变,即元素的getClass返回的还是最初自己的类型而不是Object);

      b. 如果不小心往集合里加了不相同类型的元素可能会导致类型异常(进行equals、compare比较的时候尤为明显);

      c. 由于没有类型就需要在很多地方进行强制类型转换,但是这样做增加了编程的复杂度,并且代码也不美观(臃肿),维护起来也更加困难;

    所以泛型的作用就是

      a.使集合定义元素类型,即取出元素的时候无需进行强制类型转化了,可以直接用原类型的引用接收;

      b. 一旦指定了性参数那么集合中元素的类型就确定了,不能添加其他类型的元素,否则会直接编译保存,这就可以避免了“不小心放入其他类型元素”的可能;

      c. 上述保证了如果在编译时没有发出警告,则在运行时就一定不会产生类型转化异常(ClassCastException);

    二、 泛型的概念

    定义

      Java 5开始,引入了参数化类型(Parameterized Type)的概念,使Java集合实现泛型,允许程序在创建集合时就可以指定集合元素的类型,比如List<String>就表名这是一个只能存放String类型的List;

    使用

    1、定义集合元素类型  

      定义泛型引用一定要使用尖括号指定类型参数,例如:List<String> list、Map<String, Integer>等,其中的String、Integer之类的就是类型参数;

      其次,使用构造器构造泛型对象的时候可以指定类型参数也可以不指定,例如:

             i. List<String> list = new List<String>();  // 这当然是对的

             ii. List<String> list = new List<>();  // 这样对,因为List的类型参数可以从引用推断出!

    2、定义泛型类、接口:

      使用 <T> 定义了该泛型类和接口的类型参数

      类

    public class Person<T> { ... },
    

      接口

    public interface MyGneric<E> {  
        E add(E val);  
        Set<E> makeSet();  
        ...  
    }  
    

      

    3、通配符和边界

      <? extends T> 是指 “上界通配符(Upper Bounds Wildcards)
      <? super T> 是指 “下界通配符(Lower Bounds Wildcards)

    <? extends T> 

      比如:Plate<? extends Fruit>, 只能使用 Fruit 的子类来定义泛型的实现类,

      如果 Apple 是 Fruit 的子类,那就有如下

    Plate<? extends Fruit> p=new Plate<Apple>(new Apple());
    

      

     比如:

    public Class Fruit(){}
    public Class Apple extends Fruit(){}
    
    public void test(? extends Fruit){};

    测试

    test(new Fruit());
    
    test(new Apple());
    
    test(new String()); //这个就会报错,

    <? super T> 

      比如 : Plate<? super Fruit>

        

    3.1、上下界通配符的副作用

    3.1.1、上界<? extends T>不能往里存,只能往外取

    3.1.2、 下界<? super T>不影响往里存,但往外取只能放在Object对象里

    3.2、PECS原则

      频繁往外读取内容的,适合用上界Extends。

      经常往里插入的,适合用下界Super。

     

      

        

    -------------------------------------------------------------------------------------------

    参考:

    [1] https://www.cnblogs.com/jpfss/p/9928694.html

  • 相关阅读:
    UML用例图总结
    项目管理心得:一个项目经理的个人体会、经验总结
    UML类图符号简介
    C++中栈和堆上建立对象的区别
    Win32 API
    Python
    remove extra kernel
    Create short cut
    Set Form Position
    Get folder
  • 原文地址:https://www.cnblogs.com/Jomini/p/13927817.html
Copyright © 2020-2023  润新知