栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Java】泛型的类别

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Java】泛型的类别

今天我们不讲泛型的来龙去脉,讲讲泛型到底有哪些类别,也就是Type这个接口到底有多少不同的实现(jdk中)

大家可能会疑惑,泛型还能有多种不同的类型?

这不是我前段时间写了一个库【Java】简单优雅的加载外部 jar 中的 Class|插件化

在这个库中我需要实现一个功能:通过泛型来推导数据类型来加载对应的插件内容

于是我就对我们平时常用的泛型做了一些研究

如果大家之前有去了解过相关的内容,就会知道Type接口会有一些不同的实现(jdk中)

  • Class
  • TypeVariable
  • ParameterizedType
  • WildcardType
  • GenericArrayType

那么今天我们就来看看这些类型都对应了什么写法的泛型

Class

首先Class我们接触的比较多,虽然实现了Type接口,但不是泛型,就是普通的类的类型,并不具有泛型的一些参数属性

TypeVariable

可变类型,可以得到最原始的类型信息

如我们常用的ArrayList

我们可以通过getTypeParameters来获得他的泛型信息

ArrayList.class.getTypeParameters();

但是我们只能拿到E,拿不到具体的类型,毕竟实例化之后任意的类型都有可能

那么有没有能拿到具体类型的泛型呢,我们继续往下看

ParameterizedType

参数化类型,可以获得< >中定义的具体类型

假设我们继承ArrayList并指定泛型为String

public class StringArrayList extends ArrayList {
}

这种情况下,我们就可以使用getGenericSuperclass来获得泛型信息

StringArrayList.class.getGenericSuperclass();

调用上面的方法我们就能得到一个ParameterizedType

通过ParameterizedType#getRawType()就可以获得ArrayList.class

通过ParameterizedType#getActualTypeArguments()就可以获得String.class

ParameterizedType type = (ParameterizedType) StringArrayList.class.getGenericSuperclass();

Type rawType = type.getRawType();
System.out.println(rawType);
//输出 class java.util.ArrayList

Type actualTypeArgument = type.getActualTypeArguments()[0];
System.out.println(actualTypeArgument);
//输出 class java.lang.String
WildcardType

通配符类型,可以获得泛型的类型界限

主要通过? extends或? super约束

举个例子

public class ClassArrayList extends ArrayList> {
}

其中? extends Serializable就是WildcardType

这里需要注意的是不带< >

通过WildcardType#getUpperBounds()就可以获得Serializable.class

ParameterizedType type = (ParameterizedType) ClassArrayList.class.getGenericSuperclass();

Type rawType = type.getRawType();
System.out.println(rawType);
//输出 class java.util.ArrayList

ParameterizedType actualTypeArgument = (ParameterizedType) type.getActualTypeArguments()[0];
System.out.println(actualTypeArgument);
//输出 java.lang.Class

Type argumentRawType = actualTypeArgument.getRawType();
System.out.println(argumentRawType);
//输出 class java.lang.Class

WildcardType argumentActualTypeArgument = (WildcardType) actualTypeArgument.getActualTypeArguments()[0];
System.out.println(argumentActualTypeArgument);
//输出 ? extends java.io.Serializable

Type upperBound = argumentActualTypeArgument.getUpperBounds()[0];
System.out.println(upperBound);
//输出 interface java.io.Serializable
GenericArrayType

泛型数组类型,表示泛型类型的数组类型

修改一下上面的例子

public class ClassesArrayList extends ArrayList[]> {
}

实际上就是在原本的泛型类型外又包了一层

ParameterizedType type = (ParameterizedType) ClassesArrayList.class.getGenericSuperclass();

Type rawType = type.getRawType();
System.out.println(rawType);
//输出 class java.util.ArrayList

GenericArrayType actualTypeArgument = (GenericArrayType) type.getActualTypeArguments()[0];
System.out.println(actualTypeArgument);
//输出 java.lang.Class[]

ParameterizedType genericComponentType = (ParameterizedType) actualTypeArgument.getGenericComponentType();
System.out.println(genericComponentType);
//输出 java.lang.Class

Type argumentRawType = genericComponentType.getRawType();
System.out.println(argumentRawType);
//输出 class java.lang.Class

WildcardType argumentActualTypeArgument = (WildcardType) genericComponentType.getActualTypeArguments()[0];
System.out.println(argumentActualTypeArgument);
//输出 ? extends java.io.Serializable

Type upperBound = argumentActualTypeArgument.getUpperBounds()[0];
System.out.println(upperBound);
//输出 interface java.io.Serializable
没见过的泛型写法

接下来再说一个我在查资料时见到的一种泛型写法

public class Custom {
}

不知道大家之前有没有遇到过这样的写法

然后我就研究了一下,发现这其实就是一个AND条件

上面的接口表示,这个泛型必须要实现Serializable和Cloneable,两个都要满足

所以比如ArrayList就是可以的:Custom

而且泛型中的条件可以有多个,但是最多只能有一个类,其他必须为接口

可以猜想是java只能继承一个父类但是可以实现多个接口的原因

那么今天的内容就是这样啦

其他的文章

【Java】简单优雅的加载外部 jar 中的 Class|插件化

【Spring Boot】一个注解实现下载接口

【拿来吧你】JDK动态代理

【Java】异步回调转为同步返回

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/859658.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号