Java Type接口 运行时获取泛型类型

article/2025/8/24 23:58:03

一、Type接口

Type是所有类型的父接口,他有4个子接口和一个实现类。
这里写图片描述

  1. Class比较常见,它表示的是原始类型。Class类的对象表示JVM中的一个类或接口。每个Java类在JVM里都表现为一个Class对象,可以通过“类名.class”、“对象.getClass()”、“Class.forName(“类名”)”等方式获取Class对象。数组也被映射为Class对象,所有元素类型相同且维数相同的数组都共享同一个Class对象。
  2. ParameterizedType表示的是参数化类型,例如List<String>、Map<Integer,String>、Service<User>这种带有泛型的类型。
    ParameterizedType接口中常用的方法有3个,分别是:
    (1) Type getRawType()——返回参数化类型中的原始类型,例如List<String>的原始类型为List。
    (2) Type[] getActualTypeArguments()——获取参数化类型的类型变量或是实际类型列表,例如Map<Integer,String>的实际泛型列表是Integer和String。需要注意的是,该列表的元素类型是Type,也就是说,可能存在多重嵌套的情况。
    (3) Type getOwerType()——返回的是类型所属的类型,例如存在A<T>,其中定义了内部类InnerA<T>,则InnerA<T>所属的类型是A<T>,如果是顶层类型则返回null。这种关系常见与Map<K,V>接口与Map.Entry<K,V>接口,Map<K,V>是Map.Entry<K,V>接口的所有者。
  3. TypeVariable表示的是类型变量,它用来反映的是JVM编译该泛型前的信息,例如List<T>中的T就是类型变量,它在编译时需要被转换为一个具体的类型后才能正常使用。
    该接口常用的方法有3个,分别是:
    (1) Type[] getBounds()——获取类型变量的上边界,如果未明确声明上边界则默认为Object。例如Class<K extents Person>中K的上边界就是Person。
    (2) D getGenericDeclaration()——获取声明该类型变量的原始类型,例如Test<K extents Person>中原始类型是Test。
    (3) String getName()——获取在源码中定义的名字,上例中为K。
  4. GenericArrayType表示的是数组类型且组成元素时ParameterizedType或TypeVariable,例如List<T>或T[],该接口只有Type getGenericComponentType()一个方法,它返回数组的组成元素类型。
  5. WildcardType表示的通配符类型,例如? extends Number 和 ? super Integer。
    Wildcard接口有两个方法,分别是:
    (1) Type[] getUpperBounds()——返回类型变量的上边界。
    (2) Type[] getLowerBounds()——返回类型变量的下边界。

二、ParameterizedType与TypeVariable的使用

1.未指定泛型参数的泛型类(例如:ArrayList<T>)

public class TypeTest {public static void main(String[] args) {System.out.println("接口是否是泛型类:"+ (ArrayList.class.getGenericInterfaces()[0] instanceof ParameterizedType));System.out.println("泛型类的名称:"+ ArrayList.class.getGenericInterfaces()[0].getTypeName());System.out.println("泛型类的实现:"+ ArrayList.class.getGenericInterfaces()[0].getClass());System.out.println("是否是泛型参数:"+(((ParameterizedType)ArrayList.class.getGenericInterfaces()[0]).getActualTypeArguments()[0] instanceof TypeVariable));System.out.println("泛型参数名称:"+((ParameterizedType)ArrayList.class.getGenericInterfaces()[0]).getActualTypeArguments()[0].getTypeName());System.out.println("泛型参数的实现:"+((ParameterizedType)ArrayList.class.getGenericInterfaces()[0]).getActualTypeArguments()[0].getClass());}
}//输出结果:
接口是否是泛型类:true
泛型类的名称:java.util.List<E>
泛型类的实现:class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
是否是泛型参数:true
泛型参数名称:E
泛型参数的实现:class sun.reflect.generics.reflectiveObjects.TypeVariableImpl

  在这里,我们使用的是ArrayList.class,如果使用new ArrayList<String>().getClass(),是否得到的泛型参数就是String呢?答案是否定的,因为this.getClass() 对象是被所有的不同具体类型的ArrayList实例 共享的(例如:new ArrayList<String>(), new ArrayList<Integer>() 等),所以在字节码中类型会被擦除到上限。

2.指定泛型参数的泛型类(例如:GenericSubClass<String>)

public class GenericClass<T> {
}public class GenericSubClass1<String> extends GenericClass<String> {
}public class GenericSubClass2 extends GenericClass<String> {
}public class TypeTest {public static void main(String[] args) {Class clazz = GenericSubClass1.class;//Class clazz = GenericSubClass2 .class;//Class clazz = new GenericSubClass1().getClass();//Class clazz = new GenericSubClass2().getClass();System.out.println("父类是否是泛型类:"+ (clazz.getGenericSuperclass() instanceof ParameterizedType));System.out.println("泛型类的名称:"+ clazz.getGenericSuperclass().getTypeName());System.out.println("泛型类的实现:"+ clazz.getGenericSuperclass().getClass());System.out.println("是否是泛型参数:"+(((ParameterizedType)clazz.getGenericSuperclass()).getActualTypeArguments()[0] instanceof TypeVariable));System.out.println("泛型参数名称:"+((ParameterizedType)clazz.getGenericSuperclass()).getActualTypeArguments()[0].getTypeName());System.out.println("泛型参数的实现:"+((ParameterizedType)clazz.getGenericSuperclass()).getActualTypeArguments()[0].getClass());}
}//输出结果:
父类是否是泛型类:true
泛型类的名称:com.arch.test.reflect.GenericClass<String>
泛型类的实现:class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
是否是泛型参数:true
泛型参数名称:String
泛型参数的实现:class sun.reflect.generics.reflectiveObjects.TypeVariableImpl

  不管是使用"类.class",还是使用"对象.getClass()",得到的父类的泛型参数始终是String。


http://chatgpt.dhexx.cn/article/Vv2DTLb7.shtml

相关文章

关于type_C接口

文章目录 概要&#xff1a;一、引脚定义二、六脚Type_c三、12脚Type_c四、16脚Type_c五、usb3.0 概要&#xff1a; type-C接口外观好看&#xff0c;双面插等众多优点&#xff0c;已经成为了现在主流的接口。 一、引脚定义 VBus:总线电源&#xff0c;USB PD协议可配置电压&…

TYPE-C接口引脚详解

Type-C口有4对TX/RX分线&#xff0c;2对USBD/D-&#xff0c;一对SBU&#xff0c;2个CC&#xff0c;另外还有4个VBUS和4个地线。 1、当Type-C接口仅用作传输DP信号时&#xff0c;则可利用4对TX/RX&#xff0c;从而实现4Lane传输&#xff0c;这种模式称为DPonly模式&#xff1b;…

Java反射系列--Type接口及其子接口

原文网址&#xff1a;Java反射系列--Type接口及其子接口_IT利刃出鞘的博客-CSDN博客 简介 说明 Type 是java反射机制中提供的一个接口&#xff0c;用来表示java中的所有类型的接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。&#xff08;这段话是Type源…

秒懂所有USB接口类型,USB接口大全;Type-A、Type-B、Type-C、miniUSB、microUSB区分

我们来聊一聊USB接口。由于USB-IF标准制定命名的混乱&#xff0c;大多数人都搞不清楚USB的各种版本命名&#xff0c;这里我们就好好捋一捋。。。 一、USB传输标准 自1996年USB-IF&#xff08;USB Implementers Forum&#xff09;组织发布USB 1.0标准以来&#xff0c;USB标准经…

Type-c接口及其协议介绍

一、Type-c接口支持的功能 支持接口正反插&#xff1b; 定义Vbus的电流传输能力&#xff1b; 定义功率传输角色&#xff0c;即供电端及受电端&#xff1b; 定义数据传输角色&#xff0c;主机或从机&#xff1b; 支持PD协议&#xff0c;实现大功率充电&#xff1b; 支持US…

Type-C接口相关知识

注&#xff1a;内容来自网络&#xff0c;侵删....... Type-C接口详细定义及常用功能 因为Type-C接口比Micro USB有更多的优点&#xff0c;比如&#xff0c;充电时不分正反&#xff0c;随便插&#xff1b;充电时&#xff0c;允许通过的最大电流更大等。现在越来越多的手机用Ty…

Type接口的基础知识

Type是所有类型的父接口,它有四个子接口和一个实现类 下面来看这些子接口和子类所代表的类型 Class表示的是原始类型。Class类的对象表示JVM中的一个类或者接口,每个java类在JVM都表现为一个Class对象。可以通过“类名.Class”、“对象.getClass()”或者Class.forName("…

负载均衡案例

RabbitMQ集群高可用 1.MQ节点互为镜像 2.HAproxy负载均衡 3.Keeplived高可用 RabbitMQ 的4种集群架构 RabbitMQ 的4种集群架构 - 简书 主备模式&#xff08;高可用&#xff09; 主节点提供读写&#xff0c;备用节点不提供读写。如果主节点挂了&#xff0c;就切换到备用节点…

防火墙负载均衡解决方案

近期项目当中遇到了防火墙负载均衡的需求&#xff0c;拿出来和大家探讨一下。 用户在项目中采购了4台国内某知名品牌的高端防火墙&#xff0c;原本打算通过防火墙自身集群的方式实现防火墙的负载分担和冗余部署&#xff0c;可惜防火墙厂商的答复是如果采用集群的方式&#xff0…

docker 应用负载均衡解决方案

项目中使用SpringBoot开发web应用&#xff0c;打包部署采用docker&#xff1b;之前看到通过docker-compose 来扩展容器&#xff0c;通过scale命令来扩展容器: docker-compose scale test-app4 但是试了下发现直接报错了&#xff0c;端口冲突&#xff0c;因为每个docker容器都…

Oracle 负载均衡解决方案

为什么要运用负载均衡 一般我们在数据库中的操作无非不就是增删改查这四个基本操作&#xff0c;最终数据库和磁盘文件打交道也就是读写操作。如果采用传统的一台服务器去运作&#xff0c;可能会在读写高峰时会出现一些无法预知的问题。这些我们或许可以通过优化应用代码结构&a…

两台web服务器实现负载均衡的解决方案

写在前面&#xff1a;如果此文有幸被某位朋友看见并发现有错的地方&#xff0c;希望批评指正。如有不明白的地方&#xff0c;愿可一起探讨。 总体方案 平台规划拓扑图如下&#xff1a; 总体解决方案&#xff1a; 两台web服务通过DNS实现负载均衡&#xff0c;共享NFS服务器&…

负载均衡的硬件与软件实现方案

一、什么是负载均衡 负载均衡是分摊到多个操作单元上进行执行&#xff0c;例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等&#xff0c;从而共同完成工作任务。建立在现有网络结构之上&#xff0c;它提供了一种廉价有效透明的方法扩展网络设备和服务器的带…

分布式及负载均衡解决方案

一、问题域 nginx、lvs、keepalived、f5、DNS轮询&#xff0c;每每提到这些技术&#xff0c;往往讨论的是接入层的这样几个问题&#xff1a; 1&#xff09;可用性&#xff1a;任何一台机器挂了&#xff0c;服务受不受影响 2&#xff09;扩展性&#xff1a;能否通过增加机器&…

阿里云的网站负载均衡解决方案

2015年5月&#xff0c;国务院印发了《关于进一步做好新形势下就业创业工作的意见》&#xff0c;全国范围内刮起了“大众创业&#xff0c;万众创新”的高潮。于是中关村电子市场悄然改成了创业大街&#xff0c;美食街变成了创业公社&#xff0c;就连公司的地下室也一夜之间成了创…

实现负载均衡的2种解决方案

注: NAT 为网络地址转移, 访问进来时, 最初以LVS将访问进行地址转移到内部的Nginx, 由 Nginx 进行负载均衡

mysql负载均衡完美解决方案

1.环境&#xff1a; mysql 5 ubuntu10.04 x86_64 mdb1 eth0 192.168.5.11 mdb2 eth0 192.168.5.12 sdb1 eth0 192.168.5.21 sdb2 eth0 192.168.5.22 sdb3 eth0 192.168.5.23 sdb4 eth0 192.168.5.24 haproxy…

负载均衡-

常见的负载均衡系统包括 3 种&#xff1a;DNS 负载均衡、硬件负载均衡和软件负载均衡。 DNS 负载均衡 DNS 是最简单也是最常见的负载均衡方式&#xff0c;一般用来实现地理级别的均衡。例如&#xff0c;北方的用户访问北京的机房&#xff0c;南方的用户访问深圳的机房。DNS 负…

负载均衡的解决方案

负载均衡的解决方案 前言 我们在设计分布式系统的时候往往需要考虑系统的伸缩性&#xff0c;这里所说的伸缩性指的是我们可以通过添加服务器节点的方式来提升我们整个系统的并发能力&#xff0c;这种提高伸缩性的基础原理其实就是我们所说的——负载均衡。 正文 负载均衡 …

负载均衡及解决方案

目录 一、什么是负载均衡&#xff1f; 二、负载均衡方案有几种&#xff1f; 1、基于DNS负载均衡 2、基于硬件负载均衡 3、基于软件负载均衡 三、常用的均衡算法有哪些&#xff1f; 1、轮询策略 2、负载度策略 3、响应策略 4、哈希策略 一、什么是负载均衡&#xff1f;…