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

posted @ 2020-11-04 19:52  抽象Java  阅读(584)  评论(0编辑  收藏  举报