前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java泛型

Java泛型

作者头像
devi
发布2021-08-19 16:16:29
4660
发布2021-08-19 16:16:29
举报
文章被收录于专栏:搬砖记录搬砖记录

泛型


1. 什么是泛型

在推出泛型之前,程序员通过构建元素类型为Object的集合,存储多个任意类型的数据对象;在使用该对象的过程中,程序员需要明确知道存储每个元素的数据类型(几乎不可能),否则会引发ClassCastException。

显然,类型的优点: 在不知道集合存储类型的前提下,泛型能够统一集合的元素类型——类型安全消除通过Object集合带来的强制类型转换

泛型的本质就是参数化类型,将所操作的数据类型指定为一个参数,实现动态更改。

2. 泛型类、接口

定义语法

代码语言:javascript
复制
class 类名<泛型标识,泛型标识,...>{
	private 泛型标识 变量名;
}

常用的泛型标识:

代码语言:javascript
复制
? 表示不确定的java类型
T (type) 表示具体的一个java类型
K V (key value) 分别代表java键值中的Key Value
E (element) 代表Element

如果泛型类在new的时候没有指定泛型类型,将默认使用Object来操作。

泛型类型不支持基本类型。

同一个泛型类,不同的泛型参数,本质上还是同一类型=>泛型类本身

代码语言:javascript
复制
// intGeneric是<Integer>,strGeneric是<String>
System.out.println(intGeneric.getClass()==strGenenric.getClass())  // true
// intGeneric.getClass()  ==>Generic

因此可知

指定泛型类型,不支持多态

指定泛型类型,不支持重载

如果使用泛型通配符,支持重载和多态


从泛型类派生子类

子类也是泛型类,则子类泛型标识至少要包含父类的泛型标识

子类不是泛型类,则父类的泛型类型需要显式声明 此时子类使用父类的方法,方法的返回值都会变成明确的类型

接口

实现类的实现规则跟派生子类的规则一致。

3. 泛型方法

定义格式

代码语言:javascript
复制
修饰符 <T,E,...> 返回值类型 方法名(形参){}
  • 修饰符与返回值中间的<T>非常重要,可以理解为声明该方法为泛型方法
  • 只有声明了<T>的方法才是泛型方法,泛型类中使用了泛型的成员方法不是泛型方法
  • <T>相当于声明,该方法中要使用泛型T

实例: 传入一个T类型的集合,随机返回一个T

代码语言:javascript
复制
public <T> T test(List<T> list){
	return list.get(random.nextInt(list.size()));
}

泛型类中的泛型方法的泛型标识符优先级高于泛型类 如果泛型类的泛型标识为T,泛型类中的泛型方法的标识也为T,当我们new出泛型类,指定泛型为Integer之后,再调用泛型方法,并指定泛型为String,依旧是可以的。

泛型类中使用的泛型类的成员方法,不能作为静态方法,但是泛型方法可以。


可变参数

代码语言:javascript
复制
public <E> void print(E... es){
	for(E e:es){
		sout(e);
	}
}

4. 类型通配符

类型通配符一般是?,代替具体的类型实参==>类型通配符是实参,不是形参。

类型通配符可以实现重载和多态。

类型通配上限 指定通配上限为Number,此时通配时可以使用Number及其子类

代码语言:javascript
复制
public static void test(Box<? extends Number> boxs){
	Integer box = boxs.getFirst();
}

类型通配下限 指定通配必须是该类型及其父类。

代码语言:javascript
复制
public static void test(Box<? super Number> boxs){
  	//Integer box = boxs.getFirst();
  	Object  box = boxs.getFirst();
}

5. 泛型擦除

泛型只作用于编译阶段,编译后泛型会被擦除,因此泛型能够与jdk1.5之前的版本兼容。

无限制类型擦除

在这里插入图片描述
在这里插入图片描述

如果仅仅是<T>,则统统擦除为Object

有限制类型擦除

在这里插入图片描述
在这里插入图片描述

如果存在上限,则擦除为上限

桥接方法

在这里插入图片描述
在这里插入图片描述

父类会按无限制擦除规则擦除,子类会生成一个桥接方法。

6. 泛型和数组

可以声明带泛型的数组引用,但不能直接创建带泛型的数组对象

可以通过java.lang.reflect.Array的newInstance(Class<T>, int)创建T[]数组

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-03-24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 泛型
  • 1. 什么是泛型
  • 2. 泛型类、接口
      • 接口
      • 3. 泛型方法
      • 4. 类型通配符
      • 5. 泛型擦除
      • 6. 泛型和数组
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档