当前位置: 首页 > news >正文

Java Type类

文章目录

  • Type简介
  • Type分类
    • 1. 原始类型(Class)
    • 2. 参数化类型(ParameterizedType)
    • 3. 类型变量(TypeVariable)
    • 4. 通配符类型(WildcardType)
    • 5. 泛型数组类型(GenericArrayType)


Type简介

Type是Java编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。

Type接口本身算是一个标记接口,不提供任何需要复写的方法。

Type分类

在这里插入图片描述

Type分类:

Type分类名称Type类型描述举例
原始类型ClassJava类、枚举、数组、注解、所有基本数据类型StringDateIntegerintboolean
参数化类型ParameterizedType参数化类型(泛型类型)List<String>Map<Integer,String>List<T>List<?>、List<? extends Number>List<? super Number>
类型变量TypeVariable泛型符号(不包括通配符)TKVE
通配符类型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扩展点系列&#xff1a;Springboot扩展点之ApplicationContextInitializerSpringboot扩展点之BeanFactoryPostProcessorSpringboot扩展点之BeanDefinitionRegistryPostProcessorSpringboot扩展点之BeanPostProcessorSpringboot扩展点之InstantiationAwareBeanPostPro…...

ngixn 常用配置之文件类型与自定义 log

大家好&#xff0c;我是 17 。 总结了一些 nginx 的常用配置。从入口文件开始&#xff0c;今天讲一下文件类型和自定义log 为了讲述方便&#xff0c;环境为 CentOS 7&#xff0c; nginx 版本 1.21。 配置文件入口 /etc/nginx/nginx.conf这是入口文件&#xff0c;这个文件里…...

【100个 Unity实用技能】 | Unity 通过自定义菜单将资源导出

Unity 小科普 老规矩&#xff0c;先介绍一下 Unity 的科普小知识&#xff1a; Unity是 实时3D互动内容创作和运营平台 。包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者&#xff0c;借助 Unity 将创意变成现实。Unity 平台提供一整套完善的软件解决方案&#xff…...

0.3调试opencv源码的两种方式

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

Redis的常见操作和Session的持久化

安装Redis使用yum命令&#xff0c;直接将redis安装到linux服务器&#xff1a;yum -y install redis启动redis使用以下命令&#xff0c;以后台运行方式启动redis&#xff1a;redis -server /etc/redis.conf &操作redis使用以下命令启动redis客户端&#xff1a;redis-cli设置…...

TypeScript笔记(二)

背景 上一篇文章我们介绍了TypeScript的一些特性&#xff0c;主要是其与JavaScript的比较&#xff0c;接下来我们将会开始学习Type的语法&#xff0c;这篇文章将会介绍TypeScript的数据类型。 原始数据类型 TypeScript是JavaScript的超集&#xff0c;TypeScript的数据类型就…...

【MyBatis】源码学习 03 - 类型处理器 TypeHandler

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

建造《流浪地球2》中要毁灭人类的超级量子计算机MOSS的核心量子技术是什么?

1.《流浪地球2》中的量子计算机 2023年中国最火的电影非《流浪地球2》莫属&#xff0c;在《流浪地球2》中有一个人工智能机器人MOSS &#xff0c;它的前身是“550W”超级量子计算机&#xff0c;“MOSS”是它给自己起的名字&#xff08;“550W”倒转180度就是“MOSS”&#xff…...

数据结构~七大排序算法(Java实现)

目录 插入排序 直接插入排序 希尔排序 选择排序 直接选择排序 堆排序 交换排序 冒泡排序 快速排序 递归实现 优化版本 归并排序 插入排序 直接插入排序 public class MySort {public static void insertSort(int[] array) {for (int i 1; i < array.length;…...

python练习

项目场景一&#xff1a; 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 问题描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶…...

RPC-thrift实践

参考&#xff1a;https://www.cnblogs.com/52fhy/p/11146047.html 参考&#xff1a;https://juejin.cn/post/7138032523648598030 实践 安装thrift brew install thriftthrift -version 编写thrift文件 新建文件夹thrift新建文件 结构体文件 Struct.thrift 服务文件 Service.…...

Maven:工程的拆分与聚合

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

使用uniapp创建小程序和H5界面

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

密度峰值聚类算法(DPC)

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

RabbitMQ相关问题

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

操作系统 三(存储管理)

一、 存储系统的“金字塔”层次结构设计原理&#xff1a;cpu自身运算速度很快。内存、外存的访问速度受到限制各层次存储器的特点&#xff1a;1&#xff09;主存储器&#xff08;主存/内存/可执行存储器&#xff09;保存进程运行时的程序和数据&#xff0c;内存的访问速度远低于…...

day34 贪心算法 | 860、柠檬水找零 406、根据身高重建队列 452、用最少数量的箭引爆气球

题目 860、柠檬水找零 在柠檬水摊上&#xff0c;每一杯柠檬水的售价为 5 美元。 顾客排队购买你的产品&#xff0c;&#xff08;按账单 bills 支付的顺序&#xff09;一次购买一杯。 每位顾客只买一杯柠檬水&#xff0c;然后向你付 5 美元、10 美元或 20 美元。你必须给每个…...

使用canvas给上传的整张图片添加平铺的水印

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

[安装之4] 联想ThinkPad 加装固态硬盘教程

方案&#xff1a;保留原有的机械硬盘&#xff0c;再加装一个固态硬盘作为系统盘。由于X250没有光驱&#xff0c;这样就无法使用第二个2.5寸的硬盘。还好&#xff0c;X250留有一个M.2接口&#xff0c;这样&#xff0c;就可以使用NGFF M.2接口的固态硬盘。不过&#xff0c;这种接…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...