【Java】泛型的类别

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

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

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

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

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

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

  • Class
  • TypeVariable
  • ParameterizedType
  • WildcardType
  • GenericArrayType

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

Class

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

TypeVariable

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

如我们常用的ArrayList<E>

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

ArrayList.class.getTypeParameters();

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

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

ParameterizedType

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

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

public class StringArrayList extends ArrayList<String> {
}

这种情况下,我们就可以使用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<Class<? extends Serializable>> {
}

其中? 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<? extends java.io.Serializable>

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<Class<? extends Serializable>[]> {
}

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

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<? extends java.io.Serializable>[]

ParameterizedType genericComponentType = (ParameterizedType) actualTypeArgument.getGenericComponentType();
System.out.println(genericComponentType);
//输出 java.lang.Class<? extends java.io.Serializable>

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<T extends Serializable & Cloneable> {
}

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

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

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

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

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

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

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


其他的文章

【Spring Cloud】协同开发利器之动态路由

【Spring Cloud】一个配置注解实现 WebSocket 集群方案

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

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

【Spring Boot】WebSocket 的 6 种集成方式

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值