java 基础 | 通过反射获取实体类属性

本贴最后更新于 1901 天前,其中的信息可能已经时异事殊

javaDEMO

Java 基础 Demo 站: https://www.javastudy.cloud
Java 中高级开发博客: https://www.lixiang.red
Java 学习公众号: java 技术大本营
java_subscribe

反射总述

反射通俗来说,可以通过.class 获取到类的描述信息,如这个类中有哪些方法,有哪些属性, 这些方法的入参/返回值是什么, 属性的类型是什么. 常用于各个工具类之中,也是各个框架的底层.我们平时的开发中一个类有: 类(Class), 类属性(Field),方法(Method),方法入参(Parameter),方法返回值(Return)这些东西. 反射的开始是从.class 开始的,如下所示

public void getClassInfo(Class<?> clazz){ // 获取这个类中所有的属性信息 Field[] declaredFields = clazz.getDeclaredFields(); // 获取这个类中所有的方法 Method[] declaredMethods = clazz.getDeclaredMethods(); }

以上述方法为开始,然后拿到我们想要的属性/方法,然后开始我们自己的逻辑

获取实体类的属性值

实体类中有基础属性值,有引用属性值,对于引用属性的,还需要进一步的递归反射去获取相应的属性信息,直至处理到基础性值.但遇到自己引用自己的,要注意停止递归,不然就 StackOverFlow 了
工具类代码如下:

public static Map<String,List<String>> getModelFields(Class<?> clazz){ // 选用linkedHashMap是为了有序,存复杂类型映射的结果 // key-value: com.xxx.xxx.xx <-> ["int-bName","Integer-testInter"] Map<String, List<String>> exitsMap = new LinkedHashMap<>(); doGetModelFields(clazz,exitsMap); return exitsMap; } public static void doGetModelFields(Class<?> clazz,Map<String,List<String>> map){ String clazzName = clazz.getCanonicalName(); // 为了防止循环引用,先加入到map中 List<String> list = new ArrayList<>(); map.put(clazzName,list); // 这个方法只能获取到自己类中的Field,不包含父类的 // 要注意有个this Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); String fieldName = field.getName(); if(fieldName.contains("this")){ continue; } Class<?> fieldType = field.getType(); String fullName = fieldType.getCanonicalName(); String simpleName = fieldType.getSimpleName(); list.add(simpleName+"-"+fieldName); if(!simpleClass(fieldType)){ // 判断这个是不是基础属性,如果是的话,则可以结束了 // 这里获取到的name是 com.platform.xxx.xxx.Model 这样的全路径 //如果是复杂属性的话,则先看map中有没有这个属性 if(!map.containsKey(fullName)){ // 递归去获取属性值 doGetModelFields(fieldType,map); } } } } /** * 判断这个类是否是基础类型 * @param parameterType * @return */ public static boolean simpleClass(Class<?> parameterType) { return parameterType == String.class || parameterType == Integer.class || parameterType == int.class|| parameterType == Double.class || parameterType == double.class || parameterType == Long.class || parameterType == long.class || parameterType == Float.class || parameterType == float.class || parameterType == Byte.class || parameterType == byte.class; }

测试工具类

这里我们写子两个类,A,B,C 有基础属性,有引用属性,有循环引用来做测试

public static void main(String[] args) { // 把A传进去做测试 Map<String, List<String>> modelFields = getModelFields(A.class); System.out.println(modelFields); } class A { private String aName; private String aCCC; private B b; } class B { private A a; private C c; private String bName; } class C { private String cName; }

得到的结果如下,可以看到这个 A 这个实体类的中属性都已经到 Map 中了
image.png

DEMO 总评

反射是很多工具类/框架的基础,熟练的掌握反射的开发,能为平时开发省不少时间,如我们可以用反射给应用开个后门,直接通过一个 Controller 调用所有的 Bean 来测试,如加载.class 再配合一些注解生成接口文档,如以前写的工具:Excel 和 List 互转也用到了反射,从 List 中根据某一属性查询也用到了反射,加油吧!

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3194 引用 • 8214 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...