Java Type

article/2025/9/9 21:52:24

Type 是Java 编程语言中所有类型的公共高级接口(官方解释),也就是Java 中所有类型的”爹“。其中”所有类型“的描述尤为指的关注。它并不是我们平常工作中经常使用的int、String、List、Map等数据类型,而是从Java语言角度磊说,对基本类型、引用类型向上的抽象

Java Type

    • Type 体系中的类型
    • Type 与子类,子接口的关系
      • Class
      • Type
      • ParameterizedType (参数化类型)
      • GenericArrayType (泛型数组类型)
      • TypeVariable (类型变量类型)
        • GenericDeclaration
        • 【extends 和 super的区别】
      • WildcardType (泛型表达式或者通配符表达式)
    • 示例

Type 体系中的类型

Type 体系中类型的包括

  • 原始类型(Class):不仅仅包括我们平常所指的类,还包括枚举、数组、注解等
  • 参数化类型(ParameterizedType):就是我们平常所用到的泛型List、Map
  • 泛型数组类型(GenericArrayType):并不是我们平常所使用的数组String[] 、byte[]。而是带有泛型的数组,即 T[]
  • 类型变量(TypeVariable):是各种类型变量的公共父接口,就是泛型里面的类似T、E。 在这需要强调的是,TypeVariable代表着泛型中的变量,而ParameterizedType则代表整个泛型;
  • 基本类型(Class):也就是我们所说的java 基本类型,即int、float、double等

Type类几乎在各种框架中都能看到,尤其是涉及代理,反射的业务。理解好Type类也会对今后框架封装,源码解读有很大好处

Type 与子类,子接口的关系

在这里插入图片描述

Class

当需要描述的类型是:

  • 普通的java类(比如String,Integer,Method等等)
  • 数组
  • 自定义类(比如我们自己定义的TestReflect类)
  • java基本类型(比如int,float等)
  • 可能还有其他的类

那么java会选择Class来作为这个Type的实现类,我们甚至可以直接把这个Type强行转换类型为Class。
这些类基本都有一个特点:基本和泛型无关,其他4种Type的类型,基本都是泛型的各种形态

Type

public interface Type {@RecentlyNonNulldefault String getTypeName() {throw new RuntimeException("Stub!");}
}

ParameterizedType (参数化类型)

ParameterizedType 是参数化类型,即泛型,类似List、Map<Integer, String>、List<? extends Number>带有类型参数的类型,也可以是自定义的,再调用getRawType()与getActualTypeArguments()两个方法,就可以得到声明此参数化类型的类(java.lang.Comparable)和实际的类型参数数组([? super T]),而这个? super T又是一个WildcardType类型。

 // 获取泛型的类型,比如 Map<Integer,String> 获取的是 Integer和StringType[] getActualTypeArguments();// 获取<> 前面的类型,比如 Map<Integer,String> 获取的是MapType getRawType();// 如果这个类型是某个类型所属,则获取这个所有者的类型,否则返回null,比如Map.Entry<Sting,String>,会返回MapType getOwnerType();//举例//参数,List<String>[] p3public class TestReflect {public static void test(List<TestReflect> p1,Map<String, TestReflect> p2) {}}Method[] methods = TestReflect.class.getMethods();Method method=methods[i].eques("test");Type[] types=method.getGenericParameterTypes();//第一个参数 List<TestReflect> p1Type type3=types[0];Type[] parameterizedType1=((ParameterizedType)type1).getActualTypeArguments();Class parameterizedType1_0=(Class)parameterizedType1[0];System.out.println("获取泛型的类型 :"+parameterizedType1_0.getName());//【打印log】 获取泛型的类型 :com.wf.javatype.TestReflect//第二个参数,Map<String,TestReflect> p2Type type2=types[2];Type[] parameterizedType2=((ParameterizedType)type2).getActualTypeArguments();Class parameterizedType2_0=(Class)parameterizedType2[0];System.out.println("获取泛型的类型 1:"+parameterizedType2_0.getName());Class parameterizedType2_1=(Class)parameterizedType2[1];System.out.println("获取泛型的类型 2:"+parameterizedType2_1.getName());//【打印log】//获取泛型的类型 1:java.lang.String//获取泛型的类型 2:com.wf.javatype.TestReflect

GenericArrayType (泛型数组类型)

泛型数组类型,用来描述ParameterizedType、TypeVariable类型的数组;即List[] 、T[]等

public interface GenericArrayType extends Type {/***  获取泛型数组中元素的类型,要注意的是:无论从左向右有几个[]并列,这个方法仅仅脱去最右边的[]之后剩下的内容就作为这个方法的返回值。*/Type getGenericComponentType();//举例1//参数,List<String>[] p3public class TestReflect {public static void test(List<String>[] p3,Map<String,TestReflect>[] p4) {}}Method[] methods = TestReflect.class.getMethods();Method method=methods[i].eques("test");Type[] types=method.getGenericParameterTypes();Type type3=types[0];Type genericArrayType3=((GenericArrayType)type3).getGenericComponentType();System.out.println("类型 :"+genericArrayType3.getTypeName());//【打印log】 类型 :java.util.List<java.lang.String>//举例2Type type4=types[1];Type genericArrayType4=((GenericArrayType)type4).getGenericComponentType();ParameterizedType parameterizedType4=(ParameterizedType)genericArrayType4;System.out.println("获取泛型类型 :"+parameterizedType4.getTypeName());//【打印log】获取泛型类型 :java.util.Map<java.lang.String, com.wf.javatype.TestReflect>Type[] parameterizedType4Arr=parameterizedType4.getActualTypeArguments();Class class4_0=(Class)parameterizedType4Arr[0];System.out.println("获取泛型类型 1:"+class4_0.getName());//【打印log】获取泛型类型 1:java.lang.StringClass class4_1=(Class)parameterizedType4Arr[1];System.out.println("获取泛型类型 2:"+class4_1.getName());//【打印log】获取泛型类型 2:com.wf.javatype.TestReflect
}

TypeVariable (类型变量类型)

类型变量,即泛型中的变量;例如:T、K、V等变量,可以表示任何类;在这需要强调的是,TypeVariable代表着泛型中的变量,而ParameterizedType则代表整个泛型;


public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement {// 获取泛型的上限,无显示定义(extends),默认为ObjectType[] getBounds();// 获取声明改类型变量实体(即获取类,方法或构造器名)D getGenericDeclaration();// 获取名称,即K、V、E之类名称String getName();// AnnotatedType[] getAnnotatedBounds();

认识TypeVariable之前,我们先来看另一个接口 GenericDecalaration;
GenericDeclaration 有三个直接子类 Class、Construtor、Method、Executable也就是说只能在这几种对象上进行范型变量的声明(定义)。

GenericDeclaration

//1.在类(Class)上声明(定义)类型变量
class A<T>{T a;
}//之后这里可用任意类型替换T,例如
A<String> as = new A<String>();
//是否看着有点像集合?不错,集合就是泛型的一个典型运用//2.在方法上声明(定义,方法上,类型变量声明(定义)不是在参数里边,而且必须在返回值之前,static等修饰后
public <E> void test(E e){}//3.声明(定义)在构造器上
public <K> A(K k){}//4. 第四种没有使用过,有会的大佬可以指点我一下

【注意】:类型变量声明(定义)的时候不能有下限(super),否则编译器报错。为什么T extend classA 表示泛型有上限classA 可以,因为每一个传进来的类型必定是classA(具有classA 的一切属性和方法) ,但若是T super classA,传进来的类型不一定具有classA的属性和方法,当然就不使用与泛型

【extends 和 super的区别】

关键字说明? 通配符类型
<? extends T> 表示类型的上界,表示参数化类型的可能是T 或是 T的子类
<? super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object
看了这个我是不太明白,换成白话是这个意思:
List<? extends T> 是说 这个list放的是T或者T的子类型的对象,但是不能确定具体是什么类型,所以可以get(),不能add()(可以add null值)List<? super T> 是说这个list放的是至少是T类型的对象,所以我可以add T或者T的子类型,但是get得到的类型不确定,所以不能获取

WildcardType (泛型表达式或者通配符表达式)

当需要描述的类型是泛型类,而且泛型类中的泛型被定义为(? extends xxx)或者(? super xxx)这种类型,比如List<? extends TestReflect>,这个类型首先将由ParameterizedType实现,当调用ParameterizedType的getActualTypeArguments()方法后得到的Type就由WildcardType实现。

public interface WildcardType extends Type {//得到的是类型的上边界的Type数组,实际上就是类型的直接父类,也就是extends后面的类型。//显然在当前java的设定中,这个数组只可能有一个元素,因为java现在只能extends一个类。如果实在没写extends,那他的直接父类就是Object@RecentlyNonNullType[] getUpperBounds();//得到的是类型的下边界的Type数组,有super关键字时可能会用到,经测试不会得到类型的子类,//而是只得到super关键字后面的类型,如果没写super关键字,则返回空数组。@RecentlyNonNullType[] getLowerBounds();
}

示例

public class TestReflect {public static void test(TestReflect p0,List<TestReflect> p1,Map<String, TestReflect> p2,List<String>[] p3,Map<String, TestReflect>[] p4,List<? extends TestReflect> p5,Map<? extends TestReflect, ? super TestReflect> p6) {}
}@Test
public  void main() {//获取 TestReflect 类的所有方法Method[] methods = TestReflect.class.getMethods();for (int i = 0; i < methods.length; i++) {Method method=methods[i];if(method.getName().equals("test")){System.out.println("TestReflect 的 方法: "+method.getName());Type[] types=method.getGenericParameterTypes();//第一个参数,TestReflect p0Class type0=(Class)types[0];//【打印log】 type0 :com.wf.javatype.TestReflectSystem.out.println("type0 :"+type0.getName());//第二个参数,List<TestReflect> p1//获取泛型的类型Type type1=types[1];Type[] parameterizedType1=((ParameterizedType)type1).getActualTypeArguments();Class parameterizedType1_0=(Class)parameterizedType1[0];//【打印log】获取泛型的类型 :com.wf.javatype.TestReflectSystem.out.println("获取泛型的类型 :"+parameterizedType1_0.getName());//第三个参数,Map<String,TestReflect> p2Type type2=types[2];Type[] parameterizedType2=((ParameterizedType)type2).getActualTypeArguments();Class parameterizedType2_0=(Class)parameterizedType2[0];//【打印log】 获取泛型的类型 1:java.lang.StringSystem.out.println("获取泛型的类型 1:"+parameterizedType2_0.getName());Class parameterizedType2_1=(Class)parameterizedType2[1];//【打印log】获取泛型的类型 2:com.wf.javatype.TestReflectSystem.out.println("获取泛型的类型 2:"+parameterizedType2_1.getName());}}
}

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

相关文章

常见USB接口总结:Type-A、Mini-USB、Micro-USB、Type-C等等

写在前面 最近在整理之前的笔记&#xff0c;打算把一些有价值的笔记发到CSDN分享一下。这篇总结参考的链接如下&#xff0c;结合了自己找的一些图片&#xff0c;非原创&#xff0c;侵权的话私聊我删除。 参考文章链接 https://mb.zol.com.cn/514/5147157.html 总览 标准Type-…

# USB Type-A、Type-B、Type-C及MicroUSB、MiniUSB接口定义

USB Type-A、Type-B、Type-C及MicroUSB、MiniUSB接口定义 文章目录 USB Type-A、Type-B、Type-C及MicroUSB、MiniUSB接口定义1 USB Type-A&#xff08;USB-A&#xff09;2 USB Type-B&#xff08;USB-B&#xff09;3 USB Type-C&#xff08;USB-C&#xff09;3.1 24Pin3.2 16Pi…

Java FileReader相对路径

实验一快要到DDL了&#xff0c;今天在用Javac和Java命令手动执行实验一的代码的时候发现一个问题&#xff0c;当时在IDEA中运行正常的代码&#xff0c;在javac编译手动用java执行的时候发现并不能通过&#xff0c;出问题的代码是一段&#xff08;试图&#xff09;使用相对路径来…

详解HTML的相对路径写法,详解URL相对路径的写法

虽然现在搭网站都会用各种框架&#xff0c;路径方面使用相对路径可能已经比较少了&#xff0c;不过还是总结一下吧。 假设D盘这个路径下有一些文件&#xff1a; D:\例子\html\images\ D:\例子\html\style\ D:\例子\html\example.html D:\例子\html\tupian.gif 1.若引用的资源和…

Python读取相对路径文件

例如下图目录结构: 第一种情况: 1)xxx.py想要打开a.txt,使用相对路径,有如下两种方式: 思路: xxx.py想打开的是b_file下的文件,XXX.py和b_file都在文件目录之下,两者是同级目录,因此操作就是在当前目录向下搜索,因此就可以很容易理解下面的意思了 特别提示:… \是错…

html 的相对路径和绝对路径

整篇文章是以 src 标签进行演示。 文章目录 一、相对路径 1、同级目录查找 2、上一级目录查找 3、下一级目录查找 二、绝对路径 一、相对路径 &#x1f475;相对路径&#xff1a;从当前所处的目录开始查找。 1、同级目录查找 写法&#xff1a; 1.1.直接写文件名&#xf…

java web项目 相对路径怎么写_理解JavaWeb项目中的路径问题——相对路径与绝对路径...

背景:html 在刚开始学习javaweb,使用servlet和jsp开发web项目的过程当中,一直有一个问题困扰着我:servlet 和 jsp 之间相互跳转,跳转的路径应该如何书写,才能正确的访问到相应的servlet或jsp文件?后来,在课堂上,通过老师的讲解,再加上本身的一些思考和实验,终于对we…

相对路径 各种情况

1.相对路径概念 1.1 相对路径就是相对于目标文件或&#xff08;相对虚拟目录&#xff09;的位置。&#xff0c;请看上图&#xff0c;“a.html” 文件里引用了“b.jpg”图片&#xff0c;由于“b.jpg”图片相对于“a.html”来说&#xff0c;是在同一个目录的,那么要在“a.html”文…

java中相对路径怎么写_java中如何使用相对路径读取文件

java中使用相对路径读取文件的方法:1、使用文件【File file = new File(“src/test.txt”)】方法;2、使用类的相对路径;3、使用当前线程的类加载器;4、读取web工程下的文件。 【相关学习推荐: java中使用相对路径读取文件的方法: 一、简单粗暴的 File file = new File(“…

linux 相对路径当前目录,Linux绝对路径和相对路径

前言 在使用linux远程连接操作文件时,我们就会遇到一个问题就是我们必须知道文件的存放位置,才能准确的找到文件并操作文件,在这里指明文件地址就有两种方式,那就是绝对路径和相对路径。 Linux文件目录 我们知道,Linux 系统中所有的文件(目录)都被组织成以根目录“/”开始…

golang 文件操作时相对路径问题

用os包进行Open,Create等操作的时候&#xff0c;需要传入一个path。 这个path 可以是绝对路径&#xff0c; 也可以是相对路径。 这里主要说一下相对路径的坑&#xff0c;在goland的里 // ./是你当前的工程目录&#xff0c;并不是该go文件所对应的目录。 // 比如myPro…

Java io流使用相对路径读取文件

前言&#xff1a; 在大多数时候我们会需要Java程序读取某个文件&#xff0c;不采用绝对路径读取文件&#xff0c;而采用相对路径读取。方法如下&#xff1a; 在工程目录下读取文件&#xff1a; 文件目录&#xff1a; /*** 工程目录下的相对路径读取文件数据*/ public void …

java读取文件相对路径_Java相对路径读取文件

不管你是新手还是老鸟,在程序中读取资源文件总会遇到一些找不到文件的问题,这与Java底层的实现有关,不能算bug,只要方法得当,问题还是可以解决的。 项目的文件夹结构: repathtest ├─src │ └─com │ └─lavasoft │ ├─test │ …

相对路径

相对/绝对路径 顾名思义&#xff0c;相对路径是相对于当前文件的路径。一般是较简短的&#xff0c;那么我们为什么不直接使用绝对路径&#xff0c;也就是文件存放的真实路径&#xff0c;例如&#xff1a;C:\Microsoft\test.txt。 为什么要用相对路径&#xff1f; 当我们把整个…

IDEA FileInputStream 使用相对路径读写文件

最近学习反射机制的时候Properties.load()读取本地文件流的时候怎么也找不到加载文件后面发现IDEA的默认根目录是在它的Project工程下 IDEA 的文件目录和Eclipse 的不一样 同学们可看下图 相当于eclipse的工作空间下 所以就可根据 相对路径 目录 找到文件 上图 一目了然 jus…

C#语言和doNet框架

大家首先要清楚.NET平台与C#不是一回事.这点大家一定要明白,对开发人员来讲他有两个概念。第一,它是C#、VB.net等程序运行的平台。第二,它因为为这些语言提供了丰富的类库(称之为基类库).NET CLR是什么我们现在来一起看看吧。 NET CLR是什么 对于一个将要面向.NET平台进行开发…

CSharp: QuestPDF create pdf file in donet core 6

/// <summary>/// geovindu, Geovin Du,涂聚文 Edit/// </summary>public class DuModel {private string name;private int price, quantity;/// <summary>/// /// </summary>/// <param name"name"></param>/// <param…

DoNet开源项目-基于jQuery EasyUI的后台管理系统

本文转载于 石佳劼的博客&#xff0c;有问题请到原文咨询&#xff0c;原文连接。 博主在业余时间开发了一个简单的后台管理系统&#xff0c;其中用到了 jQuery EasyUI 框架&#xff0c;上次分享过系统布局&#xff0c;参考文章&#xff1a;jQuery EasyUI 后台管理系统布局分享…

脱离.Net Framework运行doNet程序的简单方法

脱离.Net Framework运行doNet程序的简单方法(Console) 在.Net Framework下&#xff0c;你就算写一个小小的控制台程序&#xff0c;哪怕只有几K大小&#xff0c;我们必须要安装一个几十M的Framework Runtime 当然&#xff0c;现在也有一个商业的解决方案&#xff0c;来脱离框架…

ubuntu安装dotnet

ubuntu安装.net 使用包安装 将 Microsoft 包签名密钥添加到受信任密钥列表&#xff0c;并添加包存储库。 wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb sudo dpkg -i packages-microsoft-prod.deb…