Java Type类
文章目录
- Type简介
- Type分类
- 1. 原始类型(Class)
- 2. 参数化类型(ParameterizedType)
- 3. 类型变量(TypeVariable)
- 4. 通配符类型(WildcardType)
- 5. 泛型数组类型(GenericArrayType)
Type简介
Type是Java编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。
Type接口本身算是一个标记接口,不提供任何需要复写的方法。
Type分类
Type分类:
Type分类名称 | Type类型 | 描述 | 举例 |
---|---|---|---|
原始类型 | Class | Java类、枚举、数组、注解、所有基本数据类型 | String、Date、Integer、int、boolean 等 |
参数化类型 | ParameterizedType | 参数化类型(泛型类型) | List<String>、Map<Integer,String>、List<T>、List<?>、List<? extends Number>、List<? super Number> 等 |
类型变量 | TypeVariable | 泛型符号(不包括通配符) | T、K、V、E 等 |
通配符类型 | WildcardType | 通配符 | ?、? extends Number、? super Number 等 |
泛型数组类型 | GenericArrayType | 泛型数组 | List<?>[]、List<T>[]、List<String>[]、List<? extends Number>[]、T[] 等 |
获取Type:
JDK的Class、Field、Method类提供了一些列的获取类型的相关方法。
可参考文章:Java中如何获取泛型类型信息
1. 原始类型(Class)
原始类型的Type实现类为Class。这个类型与泛型无关,其它4个类型都和泛型相关。
原始类型主要包括:Java类、枚举、数组、注解、所有基本数据类型。
示例:
public class TypeTest {private String string;private Integer integer;private long lon;private int[] intArr;public static void main(String[] args) throws Exception {System.out.println(TypeTest.class.getDeclaredField("string").getGenericType() instanceof Class ? "String:是原始类型" : "String:不是原始类型");System.out.println(TypeTest.class.getDeclaredField("integer").getGenericType() instanceof Class ? "Integer:是原始类型" : "Integer:不是原始类型");System.out.println(TypeTest.class.getDeclaredField("lon").getGenericType() instanceof Class ? "long:是原始类型" : "long:不是原始类型");System.out.println(TypeTest.class.getDeclaredField("intArr").getGenericType() instanceof Class ? "int[]:是原始类型" : "int[]:不是原始类型");}
}
输出:
String:是原始类型
Integer:是原始类型
long:是原始类型
int[]:是原始类型
2. 参数化类型(ParameterizedType)
参数化类型的Type实现类为ParameterizedType。
参数化类型也就是泛型类型。
源码:
public interface ParameterizedType extends Type {Type[] getActualTypeArguments();Type getRawType();Type getOwnerType();
}
方法:
- getActualTypeArguments:获取实际类型参数的Type集合
- getRawType:获取声明此类型的类或接口的Type
- getOwnerType:如果声明此类型的类或接口为内部类,这返回的是该内部类的外部类的Type(也就是该内部类的拥有者)
示例:
public class TypeTest<T> {private Map<Integer,String> map;private List<String> list1;private List<T> list2;private List<?> list3;private List<? extends Number> list4;public static void main(String[] args) throws Exception {System.out.println(TypeTest.class.getDeclaredField("map").getGenericType() instanceof ParameterizedType ? "Map<Integer,String>:是参数化类型" : "Map<Integer,String>:不是参数化类型");System.out.println(TypeTest.class.getDeclaredField("list1").getGenericType() instanceof ParameterizedType ? "List<String>:是参数化类型" : "List<String>:不是参数化类型");System.out.println(TypeTest.class.getDeclaredField("list2").getGenericType() instanceof ParameterizedType ? "List<T>:是参数化类型" : "List<T>:不是参数化类型");System.out.println(TypeTest.class.getDeclaredField("list3").getGenericType() instanceof ParameterizedType ? "List<?>:是参数化类型" : "List<?>:不是参数化类型");System.out.println(TypeTest.class.getDeclaredField("list4").getGenericType() instanceof ParameterizedType ? "List<? extends Number>:是参数化类型" : "List<? extends Number>:不是参数化类型");System.out.println("-----------------------------------------------------------");ParameterizedType parameterizedType = (ParameterizedType) TypeTest.class.getDeclaredField("map").getGenericType();for (Type actualTypeArgument : parameterizedType.getActualTypeArguments()) {System.out.println("getActualTypeArguments 方法返回值有:" + actualTypeArgument.getTypeName());}System.out.println("getRawType 方法返回值:" + parameterizedType.getRawType().getTypeName());System.out.println("getOwnerType 方法返回值:" + (parameterizedType.getOwnerType() != null ? parameterizedType.getOwnerType().getTypeName() : "null"));}
}
输出:
Map<Integer,String>:是参数化类型
List<String>:是参数化类型
List<T>:是参数化类型
List<?>:是参数化类型
List<? extends Number>:是参数化类型
-----------------------------------------------------------
getActualTypeArguments 方法返回值有:java.lang.Integer
getActualTypeArguments 方法返回值有:java.lang.String
getRawType 方法返回值:java.util.Map
getOwnerType 方法返回值:null
3. 类型变量(TypeVariable)
类型变量的Type实现类为TypeVariable。
类型变量急速指的泛型符号(不包括通配符)。
源码:
public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement {Type[] getBounds();D getGenericDeclaration();String getName();AnnotatedType[] getAnnotatedBounds();
}
方法:
- getBounds:类型变量对应的上边界。如果没有指定上限,返回Object,可以有多个
- getGenericDeclaration:获取类型变量所在类的Type。
- getName:获取类型变量在源码中定义的名称
- getAnnotatedBounds:获取注解类型的上限数组
示例:
public class TypeTest<T> {private List<T> list2;private List<?> list3;private List<? extends Number> list4;public static void main(String[] args) throws Exception {System.out.println(((ParameterizedType)TypeTest.class.getDeclaredField("list2").getGenericType()).getActualTypeArguments()[0] instanceof TypeVariable ? "T:是类型变量" : "T:不是类型变量");System.out.println(((ParameterizedType)TypeTest.class.getDeclaredField("list3").getGenericType()).getActualTypeArguments()[0] instanceof TypeVariable ? "?:是类型变量" : "?:不是类型变量");System.out.println(((ParameterizedType)TypeTest.class.getDeclaredField("list4").getGenericType()).getActualTypeArguments()[0] instanceof TypeVariable ? "? extends Number:是类型变量" : "? extends Number:不是类型变量");System.out.println("---------------------------------------------------------------");TypeVariable typeVariable = (TypeVariable)((ParameterizedType) TypeTest.class.getDeclaredField("list2").getGenericType()).getActualTypeArguments()[0];for (Type bound : typeVariable.getBounds()) {System.out.println("getBounds 方法返回值有:" + bound.getTypeName());}System.out.println("getGenericDeclaration 方法返回值:" + typeVariable.getGenericDeclaration());System.out.println("getName 方法返回值:" + typeVariable.getName());for (AnnotatedType annotatedType : typeVariable.getAnnotatedBounds()) {System.out.println("getAnnotatedBounds 方法返回值有:" + annotatedType.getType().getTypeName());}}
}
输出:
T:是类型变量
?:不是类型变量
? extends Number:不是类型变量
---------------------------------------------------------------
getBounds 方法返回值有:java.lang.Object
getGenericDeclaration 方法返回值:class com.joker.test.generic.TypeTest
getName 方法返回值:T
getAnnotatedBounds 方法返回值有:java.lang.Object
4. 通配符类型(WildcardType)
通配符类型的Type实现类为WildcardType。
源码:
public interface WildcardType extends Type {Type[] getUpperBounds();Type[] getLowerBounds();
}
方法:
- getUpperBounds:泛型表达式的上边界(表达式中使用extends)
- getLowerBounds:泛型表达式的下边界(表达式中使用super)
示例:
public class TypeTest<T> {private List<T> list2;private List<?> list3;private List<? extends Number> list4;private List<? super Number> list5;public static void main(String[] args) throws Exception {System.out.println(((ParameterizedType)TypeTest.class.getDeclaredField("list2").getGenericType()).getActualTypeArguments()[0] instanceof WildcardType ? "T:是通配符类型" : "T:不是通配符类型");System.out.println(((ParameterizedType)TypeTest.class.getDeclaredField("list3").getGenericType()).getActualTypeArguments()[0] instanceof WildcardType ? "?:是通配符类型" : "?:不是通配符类型");System.out.println(((ParameterizedType)TypeTest.class.getDeclaredField("list4").getGenericType()).getActualTypeArguments()[0] instanceof WildcardType ? "? extends Number:是通配符类型" : "? extends Number:不是通配符类型");System.out.println(((ParameterizedType)TypeTest.class.getDeclaredField("list5").getGenericType()).getActualTypeArguments()[0] instanceof WildcardType ? "? super Number:是通配符类型" : "? super Number:不是通配符类型");System.out.println("-----------------------------------------------");WildcardType wildcardType1 = (WildcardType)((ParameterizedType) TypeTest.class.getDeclaredField("list4").getGenericType()).getActualTypeArguments()[0];System.out.println("List<? extends Number> 上边界:"+wildcardType1.getUpperBounds()[0].getTypeName());WildcardType wildcardType2 = (WildcardType)((ParameterizedType) TypeTest.class.getDeclaredField("list5").getGenericType()).getActualTypeArguments()[0];System.out.println("List<? super Number> 上边界:"+wildcardType2.getUpperBounds()[0].getTypeName());System.out.println("List<? super Number> 下边界:"+wildcardType2.getLowerBounds()[0].getTypeName());}
}
输出:
T:不是通配符类型
?:是通配符类型
? extends Number:是通配符类型
? super Number:是通配符类型
-----------------------------------------------
List<? extends Number> 上边界:java.lang.Number
List<? super Number> 上边界:java.lang.Object
List<? super Number> 下边界:java.lang.Number
5. 泛型数组类型(GenericArrayType)
泛型数组类型的Type实现类为GenericArrayType。
注意:普通类型的数组不属于泛型数组类型(如int[]、Long[]、String[])。
源码:
public interface GenericArrayType extends Type {Type getGenericComponentType();
}
方法:
- getGenericComponentType:返回泛型数组中成员类型
示例:
public class TypeTest<T> {private String[] list;private List<String>[] list1;private List<T>[] list2;private List<?>[] list3;private List<? extends Number>[] list4;private T[] list5;public static void main(String[] args) throws Exception {System.out.println(TypeTest.class.getDeclaredField("list").getGenericType() instanceof GenericArrayType ? "String[]:是泛型数组类型" : "String[]:不是泛型数组类型");System.out.println(TypeTest.class.getDeclaredField("list1").getGenericType() instanceof GenericArrayType ? "List<String>[]:是泛型数组类型" : "List<String>[]:不是泛型数组类型");System.out.println(TypeTest.class.getDeclaredField("list2").getGenericType() instanceof GenericArrayType ? "List<T>[]:是泛型数组类型" : "List<T>[]:不是泛型数组类型");System.out.println(TypeTest.class.getDeclaredField("list3").getGenericType() instanceof GenericArrayType ? "List<?>[]:是泛型数组类型" : "List<?>[]:不是泛型数组类型");System.out.println(TypeTest.class.getDeclaredField("list4").getGenericType() instanceof GenericArrayType ? "List<? extends Number>[]:是泛型数组类型" : "List<? extends Number>[]:不是泛型数组类型");System.out.println(TypeTest.class.getDeclaredField("list5").getGenericType() instanceof GenericArrayType ? "T[]:是泛型数组类型" : "T[]:不是泛型数组类型");System.out.println("------------------------------------------------------");System.out.println("List<String>[] 数组成员类型:"+((GenericArrayType) TypeTest.class.getDeclaredField("list1").getGenericType()).getGenericComponentType().getTypeName());System.out.println("List<T>[] 数组成员类型:"+((GenericArrayType) TypeTest.class.getDeclaredField("list2").getGenericType()).getGenericComponentType().getTypeName());System.out.println("List<?>[] 数组成员类型:"+((GenericArrayType) TypeTest.class.getDeclaredField("list3").getGenericType()).getGenericComponentType().getTypeName());System.out.println("List<? extends Number>[] 数组成员类型:"+((GenericArrayType) TypeTest.class.getDeclaredField("list4").getGenericType()).getGenericComponentType().getTypeName());System.out.println("T[] 数组成员类型:"+((GenericArrayType) TypeTest.class.getDeclaredField("list5").getGenericType()).getGenericComponentType().getTypeName());}
}
输出:
String[]:不是泛型数组类型
List<String>[]:是泛型数组类型
List<T>[]:是泛型数组类型
List<?>[]:是泛型数组类型
List<? extends Number>[]:是泛型数组类型
T[]:是泛型数组类型
------------------------------------------------------
List<String>[] 数组成员类型:java.util.List<java.lang.String>
List<T>[] 数组成员类型:java.util.List<T>
List<?>[] 数组成员类型:java.util.List<?>
List<? extends Number>[] 数组成员类型:java.util.List<? extends java.lang.Number>
T[] 数组成员类型:T
相关文章:

Java Type类
文章目录Type简介Type分类1. 原始类型(Class)2. 参数化类型(ParameterizedType)3. 类型变量(TypeVariable)4. 通配符类型(WildcardType)5. 泛型数组类型(GenericArrayType)Type简介 Type是Java编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型…...

Springboot扩展点之CommandLineRunner和ApplicationRunner
Springboot扩展点系列:Springboot扩展点之ApplicationContextInitializerSpringboot扩展点之BeanFactoryPostProcessorSpringboot扩展点之BeanDefinitionRegistryPostProcessorSpringboot扩展点之BeanPostProcessorSpringboot扩展点之InstantiationAwareBeanPostPro…...
ngixn 常用配置之文件类型与自定义 log
大家好,我是 17 。 总结了一些 nginx 的常用配置。从入口文件开始,今天讲一下文件类型和自定义log 为了讲述方便,环境为 CentOS 7, nginx 版本 1.21。 配置文件入口 /etc/nginx/nginx.conf这是入口文件,这个文件里…...

【100个 Unity实用技能】 | Unity 通过自定义菜单将资源导出
Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 。包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助 Unity 将创意变成现实。Unity 平台提供一整套完善的软件解决方案ÿ…...

0.3调试opencv源码的两种方式
调试opencv源码的两种方式 上两篇我们分别讲了如何配置opencv环境,以及如何编译opencv源码方便我们阅读。但我们还是无法调试我们的代码,无法以我们的程序作为入口来一步一步单点调试看opencv是如何执行的。 【opencv源码解析0.1】VS如何优雅的配置ope…...

Redis的常见操作和Session的持久化
安装Redis使用yum命令,直接将redis安装到linux服务器:yum -y install redis启动redis使用以下命令,以后台运行方式启动redis:redis -server /etc/redis.conf &操作redis使用以下命令启动redis客户端:redis-cli设置…...
TypeScript笔记(二)
背景 上一篇文章我们介绍了TypeScript的一些特性,主要是其与JavaScript的比较,接下来我们将会开始学习Type的语法,这篇文章将会介绍TypeScript的数据类型。 原始数据类型 TypeScript是JavaScript的超集,TypeScript的数据类型就…...

【MyBatis】源码学习 03 - 类型处理器 TypeHandler
文章目录前言参考目录学习笔记1、type 包中类的归类总结2、类型处理器2.1、TypeReference 类3、类型注册表3.1、TypeHandlerRegistry#getTypeHandler前言 本文内容对应的是书本第 8 章的内容,主要是关于类型处理器 TypeHandler 的学习。 这一章节的学习有些地方理…...

建造《流浪地球2》中要毁灭人类的超级量子计算机MOSS的核心量子技术是什么?
1.《流浪地球2》中的量子计算机 2023年中国最火的电影非《流浪地球2》莫属,在《流浪地球2》中有一个人工智能机器人MOSS ,它的前身是“550W”超级量子计算机,“MOSS”是它给自己起的名字(“550W”倒转180度就是“MOSS”ÿ…...
数据结构~七大排序算法(Java实现)
目录 插入排序 直接插入排序 希尔排序 选择排序 直接选择排序 堆排序 交换排序 冒泡排序 快速排序 递归实现 优化版本 归并排序 插入排序 直接插入排序 public class MySort {public static void insertSort(int[] array) {for (int i 1; i < array.length;…...

python练习
项目场景一: 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 问题描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶…...
RPC-thrift实践
参考:https://www.cnblogs.com/52fhy/p/11146047.html 参考:https://juejin.cn/post/7138032523648598030 实践 安装thrift brew install thriftthrift -version 编写thrift文件 新建文件夹thrift新建文件 结构体文件 Struct.thrift 服务文件 Service.…...

Maven:工程的拆分与聚合
Maven 拆分与聚合创建父工程创建子模块pom.xml配置示例拆分与聚合 在 Maven 中, 拆分是将一个完整的项目分成一个个独立的小模块,聚合是将各个模块进一步组合,形成一个完整的项目。接下来简单示例拆分与聚合的过程。 创建父工程 父工程,一个pom工程,目录结构简单,只需有…...

使用uniapp创建小程序和H5界面
uniapp的介绍可以看官网,接下来我们使用uniapp创建小程序和H5界面,其他小程序也是可以的,只演示创建这2个,其实都是一套代码,只是生成的方式不一样而已。 uni-app官网 1.打开HBuilder X 选择如图所示,下…...

密度峰值聚类算法(DPC)
密度峰值聚类算法目录DPC算法1.1 DPC算法的两个假设1.2 DPC算法的两个重要概念1.3 DPC算法的执行步骤1.4 DPC算法的优缺点matlab代码密度计算函数计算delta寻找聚类中心点聚类算法目录 DPC算法 1.1 DPC算法的两个假设 1)类簇中心被类簇中其他密度较低的数据点包围…...

RabbitMQ相关问题
文章目录避免重复消费(保证消息幂等性)消息积压上线更多的消费者,进行正常消费惰性队列消息缓存延时队列RabbitMQ如何保证消息的有序性?RabbitMQ消息的可靠性、延时队列如何实现数据库与缓存数据一致?开启消费者多线程消费避免重复消费(保证消…...

操作系统 三(存储管理)
一、 存储系统的“金字塔”层次结构设计原理:cpu自身运算速度很快。内存、外存的访问速度受到限制各层次存储器的特点:1)主存储器(主存/内存/可执行存储器)保存进程运行时的程序和数据,内存的访问速度远低于…...
day34 贪心算法 | 860、柠檬水找零 406、根据身高重建队列 452、用最少数量的箭引爆气球
题目 860、柠檬水找零 在柠檬水摊上,每一杯柠檬水的售价为 5 美元。 顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。 每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个…...

使用canvas给上传的整张图片添加平铺的水印
写在开头 哈喽,各位倔友们又见面了,本章我们继续来分享一个实用小技巧,给图片加水印功能,水印功能的目的是为了保护网站或作者版权,防止内容被别人利用或白嫖。 但是网络中,是没有绝对安全的,…...

[安装之4] 联想ThinkPad 加装固态硬盘教程
方案:保留原有的机械硬盘,再加装一个固态硬盘作为系统盘。由于X250没有光驱,这样就无法使用第二个2.5寸的硬盘。还好,X250留有一个M.2接口,这样,就可以使用NGFF M.2接口的固态硬盘。不过,这种接…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...