Java Type类

news2024/9/24 5:28:13

文章目录

  • 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/355269.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java数据结构-栈、队列常用类(Stack、ArrayDeque、LinkedLList)

数据结构的三要素包括&#xff1a;逻辑结构、存储结构、数据的运算。逻辑结构描述的是数据之间的逻辑关系&#xff0c;分为线性结构&#xff08;线性表&#xff08;数组、链表&#xff09;、栈、队列&#xff09;和非线性结构&#xff08;图、树、集合&#xff09;。物理结构也…

服务器是干什么用的?

首先&#xff0c;什么是服务器&#xff1f;服务器是提供计算服务器和网络服务的设备。服务器和计算机由CPU、硬盘、内存、系统总线等组成。比如我们访问一个网站&#xff0c;点击这个网站会发出访问请求&#xff0c;服务器会响应服务请求&#xff0c;进行相应的处理&#xff0c…

在windows中使用tomcat搭建Jenkins

1、 准备环境&#xff1a;JDK JDK官网下载&#xff1a;https://download.oracle.com/java/19/latest/jdk-19_windows-x64_bin.msi 2、 tomcat包 tocat官网下载&#xff1a;https://tomcat.apache.org/download-90.cgi 3、 Jenkins.war包 Jenkins官网下载&#xff1a;https://mi…

GEE学习笔记 七十六:【GEE之Python版教程十】字典

python中万物皆对象&#xff0c;字典在其他的语言中也有称之为对象&#xff0c;无论怎么称呼它其实就是 {key:value} 这种格式。 依然是运行代码前先注册GEE import ee ee.Initialize() 1、字典的API 首先看一下GEE的python版API&#xff08;Welcome to GEE-Python-API’s d…

曾经的月薪3K,现在的月薪25K,我的测试经验值得你的借鉴

成功不能复制&#xff0c;但经验却可以借鉴&#xff01;从曾经的月薪3K&#xff0c;到现在的月薪25K&#xff0c;我觉得我的涨薪之路的的确确可以给很多人一些参考。授人以鱼不如授人以渔&#xff0c;所以&#xff0c;今天我也想把我的经验分享给大家&#xff0c;希望可以帮助一…

Unity New Input System

安装 Input System是新的输入系统&#xff0c;用来取代旧的Input Manager&#xff0c;方便接收不同的输入设备 在Package Manager里安装 安装后可以选择只使用新的Input System&#xff0c;或选Both两者都使用&#xff0c;考虑很多插件还在使用旧的Input Manager&#xff0c…

nacos discovery和config

微服务和nacos版本都在2.x及之后。1、discovery用于服务注册&#xff0c;将想要注册的服务注册到nacos中&#xff0c;被naocs发现。pom引入的依赖是&#xff1a;yml配置文件中&#xff1a;2、config用于获取nacos配置管理->配置列表下配置文件中的内容pom引入的依赖是&#…

Android问题解决方案(一):Android 打空包后提示没有”android:exported“的属性设置

Android 打空包后提示没有”android:exported“的属性设置Android 打空包后提示没有”android:exported“的属性设置1、问题&#xff1a;2、文档3、参考链接&#xff1a;4、解决方案&#xff1a;Android 打空包后提示没有”android:exported“的属性设置 1、问题&#xff1a; …

SpringMVC——基础知识

基本概念 SpringMVC是基于servlet api构造的原始web框架&#xff0c;全称是Spring Web MVC 而MVC的全称是Model View Controller&#xff0c;翻译成中文分别是“模型”&#xff0c;“视图”&#xff0c;“控制器”&#xff0c;这是一种软件的架构模式 Model&#xff1a;用来…

JavaScript:简单理解防抖和节流,如何定义防抖和节流函数?

防抖 防抖函数&#xff0c;就是防止抖动&#xff0c;避免事件重复触发。比如监听输入框的输入&#xff0c;不应该在用户每输入一个字符就触发监听&#xff0c;而是在用户输入结束后再来监听。 流程为&#xff1a; 1、事件触发&#xff1b; 2、开启定时器&#xff1b; 3、当事…

致远OAA6版安装

准备工作&#xff0c;操作系统winserver2019&#xff0c;sqlserver2019。致远OA安装包0.SeeyonInstall.zip相关下载&#xff1a;winserver2019下载地址&#xff1a;cn_windows_server_2019_updated_july_2020_x64_dvd_2c9b67da.iso magnet:?xturn:btih:22A410DEA1B0886354A34D…

实用版ChatBing论文阅读助手教程+新测评

实用版ChatBing论文阅读助手新测评 AI进化&#xff08;更新&#xff09;的速度太快了&#xff01;距离我上次的【Chat嘴硬&#xff01;基于NewBing的论文调研评测报告】&#xff0c;才四天&#xff0c;它已经进化到快能用的地步了&#xff01; 这次是我刷B站看到热门推荐&…

美团 PK 抖音,内容与商业化之间的较量谁能赢?

□ 最近事件&#xff1a;根据Tech星球报道&#xff0c;近期美团升级短视频、直播等内容建设&#xff1b;并且宣称调整战略&#xff0c;发力短视频和直播 1、美团外卖APP商家信息流中&#xff0c;会出现约30秒的短视频内容&#xff0c;视频偏向于种草&#xff0c;主要是向消费者…

明美新能在创业板IPO过会:计划募资4.5亿元,2022年营收约39亿元

2月17日&#xff0c;深圳证券交易所披露的信息显示&#xff0c;广州明美新能源股份有限公司&#xff08;下称“明美新能”&#xff09;获得上市委会议审议通过。本次冲刺上市&#xff0c;明美新能计划募资4.50亿元&#xff0c;德邦证券为其保荐机构。 据介绍&#xff0c;明美新…

响应式编程(Reactive Programming)介绍

什么是响应式编程? 在互联网上有着一大堆糟糕的解释与定义。Wikipedia 一如既往的空泛与理论化。Stackoverflow 的权威答案明显不适合初学者。Reactive Manifesto 看起来是你展示给你公司的项目经理或者老板们看的东西。微软的 Rx terminology"Rx Observables LINQ S…

WebGPU学习(1)---在WebGPU上绘制三角形

在本文中&#xff0c;我们将使用 WebGPU 绘制一个简单的三角形。示例地址 初始化 WebGPU WebGPU 初始化的流程比 WebGL 要更复杂。 在 WebGL 中&#xff0c;我们只需从 Canvas 元素获取 WebGL 渲染上下文&#xff0c;如 getContext(“webgl” 或者 “webgl2”)。 const gl …

浙江工业大学关于2023年MBA考试初试成绩查询及复试阶段说明

根据往年的情况&#xff0c;2023浙江工业大学MBA考试初试成绩可能将于2月21日公布&#xff0c;为了广大考生可以及时查询到自己的分数&#xff0c;杭州达立易考教育为大家汇总了信息。 1、初试成绩查询&#xff1a;考生可登录中国研究生招生信息网“全国硕士研究生招生考…

Redis学习【9】之Redis RDB持久化

文章目录一 AOF(Append Only File) 持久化二 AOF 基础配置2.1 AOF的开启2.2 文件名配置2.3 混合式持久化开启2.4 AOF 文件目录配置三 AOF 文件格式3.1 Redis 协议3.2 查看 AOF 文件3.3 清单文件3.4 Rewrite 机制3.4.1 rewrite简介3.4.2 rewrite 计算策略3.4.3 手动开启 rewrite…

极客时间左耳听风-高效学习

左耳听风——高效学习篇 P95 | 高效学习&#xff1a;端正学习态度 本人真实⬇️⬇️⬇️⬇️ “ 大部分人都认为自己爱学习&#xff0c;但是&#xff1a; 他们都是只有意识没有行动&#xff0c;他们是动力不足的人。 他们都不知道自己该学什么&#xff0c;他们缺乏方向和目标。…

基于RK3588的嵌入式linux系统开发(四)——uboot镜像下载(基于RKDevTool工具)

官方提供的SDK中包含RKDevTool工具&#xff08;RKDevTool_Release_v2.92&#xff09;和相应的驱动&#xff08;DriverAssitant_v5.1.1&#xff09;。本节主要介绍在windows操作系统环境下利用RKDevTool下载以上生成的uboot镜像和bootloader镜像。注意&#xff1a;本节使用的板卡…