Java的泛型


前言:
有时候我们在看别人代码的时候会看到这样的形式: List <String>,却不懂得是什么意思?所以我现在就来说一说这个泛型。

一、泛型的定义

  1. 泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
<T>: 定义一个泛型的变量, 默认值: Object
 在类上定义: 这个类称为泛型类
 泛型变量在类的构造方法,非静态方法的参数
 非静态方法的返回值使用
 属性的数据类型

 不能在静态方法上使用 

例子:

// 定义一个string参数的list集合
List<String> arrayList = new ArrayList<String>();
  1. 静态泛型方法, 这个泛型变量需要在静态方法上声明,再使用
public static  <E> E 方法名(E 参数名){

}

//定义一个参数为integer 和 string的集合
public static Map<Integer,String> mapPoker = new HashMap<>();

二、泛型的使用

1、普通方法

//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时,必须指定T的具体类型

public class Generic<T>{ 
    //key这个成员变量的类型为T,T的类型由外部指定  
    private T key;
}

常用的 T,E,K,V,? 本质上这些个都是通配符,没啥区别,只不过是编码时的一种约定俗成的东西。比如上述代码中的 T ,我们可以换成A-Z 之间的任何一个 字母都可以,并不会影响程序的正常运行,但是如果换成其他的字母代替 T,在可读性上可能会弱一些。通常情况下,T,E,K,V,? 是这样约定的:

(1) ? 表示不确定的 java 类型
(2) T (type) 表示具体的一个java类型
(3) K V (key value)分别代表java键值中的Key Value
(4) E (element) 代表Element

2、泛型接口
泛型接口与泛型类的定义及使用基本相同。泛型接口常被用在各种类的生产器中

//定义一个泛型接口
public interface Generator<T> {
    public T next();
}

3、 使用其他定义好的泛型类,或者泛型方法

比如: 集合类都是jdk已经定义好的泛型类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VpDdzDnI-1661688957786)(../../../../%E5%AE%9E%E8%AE%AD/%E5%AE%9E%E8%AE%AD%E4%B8%89/%E7%AC%94%E8%AE%B0/2022.8%E6%9C%88%E4%BB%BD%E7%AC%94%E8%AE%B0/8-9%E7%AC%94%E8%AE%B0/assets/image-20220809085616242.png)]

4、<E>: 泛型类型变量

使用: 给泛型类型变量赋值: 在创建这个类的时候,使用<具体数据类型>赋值

泛型赋值数据类型只能是类类型,不能是基本数据类型

泛型没有继承关系

泛型变量没有赋值: 就是Object

三、泛型通配符

? 任意数据类型

定义一个方法, 接收一个泛型类类型的变量, 不确定泛型类的泛型变量类型, 这个参数不能类<Object>,因为泛型没有继承,
使用?通配符

使用通配符的泛型变量, 只能只读的

例子:

> static void reverse(List<?> list)  //把List集合的元素反转

四、泛型限制

泛型上限:

  • 格式: 类型名称<? extends 类> 对象名称
  • 意义: 只能接收该类型及其子类
public void showKeyValue1(Generic<? extends Number> obj){
   Log.d("泛型测试","key value is " + obj.getKey());
} 

泛型下限:

  • 格式:类型名称<? super 类> 对象名称
  • 意义:只能接收该类型及其父类类型
private <T> void test(List<? super T> dst, List<T> src){
   for (T t : src) {
       dst.add(t);
   }
}
public static void main(String[] args) {
  List<Dog> dogs = new ArrayList<>();
  List<Animal> animals = new ArrayList<>();
  new Test3().test(animals,dogs);
}
// Dog 是 Animal 的子类
class Dog extends Animal {

}

五、泛型集合

常用方法:

static <T> boolean addAll(Collection<? super T> c, T... elements)  
//把数组的元素添加到集合
static void reverse(List<?> list)  //把List集合的元素反转
static void shuffle(List<?> list)  //随机打乱List集合元素的顺序
static <T extends Comparable<? super T>>
void sort(List<T> list)  //自然排序
static <T> void sort(List<T> list, Comparator<? super T> c)  //指定排序

最后:本文中的例子主要是为了阐述泛型中的一些思想而简单举出的,并不一定有着实际的可用性。其实很多人都以为泛型只是在集合中,但是,在实际的编程过程中,自己可以使用泛型去简化开发,且能很好的保证代码质量。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小温豌豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值