Java进阶 - 泛型

作用

泛型(generics) 是在JDK 5中引入的新特性,它的本质其实是类型参数化。

泛型可以在编译时对类型进行安全检测(如果元素的类型与要求的不一致,在编译阶段就会检测出有错误,不需要进入到运行阶段才能发现类型不一致)。

泛型保证了类型的安全性(在获取集合中的元素时,也不需要进行强制类型转换,程序会自动进行隐式转换,这就保证了数据的安全性),也提高了代码的执行效率。

泛型作为“代码模板”,实现了 一套代码对各种类型的套用, 提高了代码的可重用性。

使用场景

基于泛型的这些特性和作用,可以用在如下场景中:

  1. 泛型集合:在各种集合中使用泛型,保证集合中元素的类型安全;
  2. 泛型方法:在各种方法中使用泛型,保证方法中参数的类型安全;
  3. 泛型类:在类的定义时使用泛型,为某些变量和方法定义通用的类型;
  4. 泛型接口:在接口定义时使用泛型,为某些常量和方法定义通用的类型;
  5. 泛型加反射:泛型也可以结合反射技术,实现在运行时获取传入的实际参数等功能。

但是我们要注意,无论我们在哪个地方使用泛型,泛型都不能是基本类型。

泛型标记符

泛型的名称其实是可以随意写的,但我们在实际开发时,为了尽量做到见名知意,还是要尽量采用有意义的名称,通常会使用如下几个常用字母:

  • E - Element (在集合中使用,因为集合中存放的是元素)
  • T - Type(Java 类)
  • K - Key(键)
  • V - Value(值)
  • N - Number(数值类型)
  • ? - 表示不确定的 java 类型

逆变与协变

型变: 分为逆变和协变, 与不变对应, 用来描述类型转换后的继承关系;

  • 协变(extends)

例如:Crate<Orange> 是 Crate<? extends Fruit> 的子类型,上界 Fruit;

协变指定了上界(限定父类,允许往下的子类), 限制调用 set 方法, 允许调用get方法来保证类型的安全。所以返回类型只能用协变(extends)。

  • 逆变(super)

例如:Crate<Fruit> 是 Crate<? super Orange> 的子类型,下界 Orange;

逆变限定了下界(限定子类,允许往上的父类), 允许调用 set 方法, 并可以将Object赋值给它。所以

参数类型只能用逆变(super)。

静态泛型方法

静态泛型方法要在返回值之前使用泛型声明此方法为泛型方法:

        错误写法:public static BaseResponse<T> success() {}
        正确写法:public static <T> BaseResponse<T> success() {}

原理

        在java中泛型只是一个占位符,必须在传递类型后才能使用。就泛型类而言,类实例化时才能传递真正的类型参数,由于静态方法的加载先于类的实例化,也就是说类中的泛型还没有传递真正的类型参数时,静态方法就已经加载完成。显然,静态方法不能使用/访问泛型类中的泛型。

        这和静态方法不能调用普通方法/访问普通变量类似,都是因为静态申明与非静态申明的生命周期不同。因此如果方法没有声明为泛型方法的话,那么这个方法就不能访问泛型、把泛型当成返回值等涉及到泛型的操作。

        因此也不能定义泛型静态变量,因为静态变量在java程序一运行时就已经被载入内存,而此时它的类型无法确定,而开辟空间必须知道类型,两者矛盾。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值