首页 > 编程语言 >java反射field相关知识

java反射field相关知识

时间:2023-01-10 11:24:45浏览次数:58  
标签:反射 java List Class field 类型 ParameterizedType type class

Class c = ArrayList.class;

c.isPrimitive(); //判断c是否为基本数据类型

c.isAssignableFrom(List.class); //判断c是否是List类的子类或父类

c.getGenericType(); //得到泛型类型

一、判断指定class是否基础类型或者包装类型

方法一

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.9</version>
</dependency>

ObjectUtil.isBasicType 判断是否为基本类型,包括包装类型和原始类型。

包装类型:

  • Boolean
  • Byte
  • Character
  • Double
  • Float
  • Integer
  • Long
  • Short

原始类型:

  • boolean
  • byte
  • char
  • double
  • float
  • int
  • long
  • short
boolean basicType = ObjectUtil.isBasicType(a);

二、普通类型的变量直接field.getType()即可以获取到他们的类型

Class type = field.getType();

assertEquals(type,String.class);

三、数组类型

数组类型不像其他的类型可以通过isAssignableFrom()函数来进行判断,他需要使用isArray() 来判断该type是否是一个数组类型,然后使用getComponentType() 获取他的元素的类型

Class> type = field.getType();
//一般来说,判断是否是某种类型是可以使用isAssignableFrom
// 判断是否是数组类型比较特殊,要使用isArray()这个函数
if (type.isArray()){
  //获得数组的类型,使用getComponentType()这个方法
  Class componentType = type.getComponentType();

  assertEquals(componentType,Integer.class);
}

四、带泛型的类型

带泛型的类型就是类似于List这样的类型,我们现在的任务就是获取到String这个类型。

ParameterizedType表示参数化的类型,例如Collection这样的类型。我们可以通过getGenericType()方法获得该子类,当你的类型带有参数的时候就会返回ParameterizedType,否则会返回普通的类型(class)

Class<T> tc = T.class;

Field[] fields = tc.getDeclaredFields();
for (Field f : fields) {
  Class fc = f.getType();
  //判空
  if (fc == null){
    continue;
  }
  if(fc.isPrimitive()){
    System.out.println("基本数据类型: " + f.getName() + "  " + fc.getName());
  }else{
    if(fc.isAssignableFrom(List.class)){ //判断是否为List
      System.out.println("List类型:" + f.getName());
      //如果是List类型,得到其Generic的类型
      Type gt = f.getGenericType();
      //判断是否泛型类型,例:List list = new ArrayList();这种会为false
      if(gt instanceof ParameterizedType){
        ParameterizedType pt = (ParameterizedType)gt;
        Class lll = (Class)pt.getActualTypeArguments()[0];
        System.out.println("\t\t" + lll.getName());
      }
    }
  }
}

五、复杂嵌套

如果我们有一个嵌套List,我们想拿到嵌套在最里面的类型,那么我们可以这么做呢?

//其实我们可以使用递归的思想去获得最里面的类型
Field field = Some.class.getDeclaredField("matrix");
assertEquals(getBaseType(field.getGenericType()),Double.class);


public static Type getBaseType(Type genericReturnType){
  Objects.requireNonNull(genericReturnType);
  //如果出入的type是ParameterizedType并且是List类型则进入递归便利
  //第二个是将传入的类型转换为ParameterizedType类型,然后getRawType即自己的类型,强转为class类型后进行对比
  if (genericReturnType instanceof ParameterizedType &&
    List.class.isAssignableFrom((Class)(((ParameterizedType) genericReturnType).getRawType()))){
    Type[] actualTypeArguments = ((ParameterizedType)genericReturnType).getActualTypeArguments();
    Type type = actualTypeArguments[0];
    return getBaseType(type);
  }else{
  	return genericReturnType;
  }
}

六、多个泛型参数

Field field = Some.class.getDeclaredField("map");
Type type = field.getGenericType();
if (type instanceof ParameterizedType){
  ParameterizedType parameterizedType = (ParameterizedType)type;
  Type[] actualTypes = parameterizedType.getActualTypeArguments();
  assertEquals(actualTypes[0],String.class);
  assertEquals(actualTypes[1],Class.class);
}else{
	throw new IllegalStateException();
}

站在巨人肩膀上摘苹果

https://blog.csdn.net/weixin_39590601/article/details/114359916

https://blog.csdn.net/weixin_43831204/article/details/107670994

标签:反射,java,List,Class,field,类型,ParameterizedType,type,class
From: https://www.cnblogs.com/eternityz/p/17039597.html

相关文章

  • 如何理解Java的一处编译处处运行
    要理解Java的一处编译处处运行这句话,首先需要知道平台的概念;什么是平台 CPU处理器与操作系统的整体叫平台。CPU:每种CPU又有特定的指令集;操作系统:不同的操作系统支......
  • 14个非常棒的 JavaScript 游戏开发框架推荐
     ​​LimeJS​​​​​​这是一个基于HTML5游戏框架,用于快速构建运行于现代触摸屏和桌面浏览器的游戏(需要***访问)。 ​​Impact​​​​​​ 这是一个专业的JavaScript......
  • Java循环运行时暂停一段时间
    GitHub项目地址Gitee项目地址Java在运行for循环时,希望可以每个循环暂停一段时间。使用sleep方法即可:for(inti=0;i<10;i++){try{System.ou......
  • 【项目源码】基于JavaEE的健康管理系统
    随着网络技术的不断发展,网站的开发与运用变得更加广泛。这次采用java语言SSH框架(Spring,Struts,Hibernate)设计并实现了面向特定群体的健康管理平台。该网站主要有教师饮食管......
  • [项目源码] JavaWeb校园宿舍管理系统
     jsp校园宿舍管理系统源码,采用Servlet+JSP+MySQL。包含数据库文件,界面采用bootstrap,简洁大方。      项目导入eclipse后的目录结构如下: 关注下面公众号,下载源码原......
  • Java循环运行时暂停一段时间
    GitHub项目地址Gitee项目地址Java在运行for循环时,希望可以每个循环暂停一段时间。使用sleep方法即可:for(inti=0;i<10;i++){try{System.o......
  • java循环结构中局部变量和成员变量
    前言在前两篇文章中,壹哥给大家讲解了Java里的条件分支,包括if和switch两种情况。我们知道,除了条件分支结构,还有循环结构,所以接下来的一个学习重点就是Java里的循环。但在学......
  • java后端解决跨域问题
    一、问题来源最近同事开发一个功能,提供接口给第三方调用,第三方调用时直接前端进行调用的因此触发了跨域拦截,报错如下: 二、解决方法可以要求第三方在自己后端......
  • Java面试题Day07
    1.什么是反射机制,反射机制的优缺点.Java反射机制是在运行过程中,对于任意一个类,都可以知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属......
  • [JAVA]es整合多数据源
    配置文件spring:elasticsearch:rest:uris:${ES_URL:http://***:9200}username:${ES_USERNAME:***}password:${ES_PASSWORD:***}elastic:m......