欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

新手笔记——泛型

程序员文章站 2022-06-28 16:36:39
泛型是什么泛型的本质是参数化类型,所操作的数据类型被指定为一个参数为什么使用泛型减少类型转换限制类型,避免无谓的强制类型转换类型转换更安全泛型的应用分类泛型类泛型类定义:泛型类就是有一个或多个类型变量的类——摘自Java核心技术卷1 章节8.2//使用举例public class Plate{//T或K代表一种数据类型,必须写在返回值类型之前,使用时传入正常的数据类型}泛型方法泛型方法定义:带有类型参数的方法//使用举例p...

泛型是什么

泛型的本质是参数化类型,所操作的数据类型被指定为一个参数

为什么使用泛型

  • 减少类型转换
  • 限制类型,避免无谓的强制类型转换
  • 类型转换更安全

泛型的应用

分类

  • 泛型类
    泛型类定义:

泛型类就是有一个或多个类型变量的类 ——摘自Java核心技术卷1 章节8.2

//使用举例
public class Plate<T,K>{		//T或K代表一种数据类型,必须写在返回值类型之前,使用时传入正常的数据类型
}
  • 泛型方法
    泛型方法定义: 带有类型参数的方法
//使用举例
public class Plate<T>{						//泛型类
	public <K> void  allplePlate(){		//泛型方法,T、K代表一种数据类型,必须写在返回值前边,如果void写成泛型T代表返回值类型是T
	}
}
  • 泛型接口
    泛型接口和泛型类几乎一样,用法差不多
    注意事项
  • 一般T代表任何类、E(Element)代表每一个元素、K代表Key、V代表Value
  • 上述分类中,不同类型的泛型,即使使用的参数是同样的字母,他们也不一样,要根据实际传入的数据类型判断

有界泛型&泛型继承(泛型不支持继承!!!!)

  • 类的声明:
pubic class Plate <T extends Fruit> {}
//由此类new的对象的数据类型只能是Fruit及其子类型
  • 泛型不支持继承
Plate <Fruit> pf = null;
Plate <Apple>`pa = new Plate();			//class Apple extends Fruit
pf = pa;	//不能这样赋值,因为如果它这样使用成功了,pf无法再装banana,与原意不符
Plate<Fruit> plate = new Plate<Apple>();
  • 为解决此问题,引用泛型通配符("?" 表示不确定的)
  • <?> //无限定通配符
Plate <?> pw = null;
pw = pa;	//可以运行,获取元素都是Object
pw.set(new Apple());	//错误不能放入元素 丧失了存储能力
  • <? extends T> //有上限通配符 泛型的具体参数必须是T或者他的子类
Plate<?extends Fruit> plate = new Plate<Apple>();	
//通过 获取的元素都变成Fruit 同样丧失了存储能力,因为不能确定他的具体类型
  • <? super T> //有下限通配符 泛型的具体参数必须是T或者他的父类
Plate<? super Fruit> plate = new Plate<Food>();	//通过 获取的元素都变成了Object
plate.set(new Apple());	//通过 Fruit及其子类型都可以存储

泛型的PECE原则 Peroducer Extends, Consumer Super

Peroducer Extend

  • 如果我们需要一个Plate提供类型为T的数(希望从Plate中读取T类型的数据),那么我们需要使用extends
  • 例如Plate<? extends Fruit >,但是我们不能向这个Plate添加数据

Consumer Super

  • 如果我们需要一个Plate来消费T类型的数据(即希望将T类型的数据写入Plate中),那么我们需要使用super
  • 例如Plate<? super Fruirt> 但是这个Plate不能保证从他读取的数据的类型
  • 如果我们希望既能读取,也能写入,那么我们就必须明确地声明泛型参数的类型
  • 例如Plate,从该容器中读取到的只能是Apple类型地数据,我们也只能写入Apple类型地数据

类型擦除

泛型的本质上只是一种编译特性,是一个“语法糖”,因为带泛型参数的代码经过编译以后的泛型信息是会被擦除的,不会保留到运行期

类型擦除的两种方式

  • 通过反射绕过泛型限制操作
  • 通过反编译

Java语言中的泛型基本上完全再编译器中实现,由编译器执行类型检查和类型推断,然后生成普通的非泛型的字节码

使用擦除实现泛型的原因:类型安全

本文地址:https://blog.csdn.net/weixin_42560422/article/details/109601170