littlerookie 发表于 2023-7-24 10:41

class工具类-获取上级类或者接口集

本帖最后由 littlerookie 于 2023-7-27 09:25 编辑


```
package xxx.xxx.utils.external.clazz;

import cn.hutool.core.collection.CollUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* @Description: class工具类
*/
public enum ClassUtil {

    ;

    /**
   * 最多循环次数的极限值
   */
    private final static int LIMIT_FOR_COUNT = 100;

    /**
   * Object类型对象
   */
    private final static Class<Object> OBJECT_CLASS = Object.class;

    /**
   * @Param clazz 指定的class对象
   * @description 获取指定类的父类及以上继承类class对象集合(包含当前类 ( 如果是类的话)的class对象)
   */
    public static List<Class<?>> getSuperClassList(Class<?> clazz) {
      try {
            if (clazz == null || clazz.isInterface()) {
                return Collections.emptyList();
            }
            List<Class<?>> resultList = new ArrayList<>();
            resultList.add(clazz);
            //上一个目标类的class对象
            Class<?> lastTargetClass = ClassUtil.getSuperClass(clazz);
            if (lastTargetClass == null) {
                return resultList;
            }
            resultList.add(lastTargetClass);
            int currentCount = 0;
            while (currentCount < LIMIT_FOR_COUNT) {
                ++currentCount;
                Class<?> targetClass = ClassUtil.getSuperClass(lastTargetClass);
                //将此值赋值给lastTargetClass
                lastTargetClass = targetClass;
                if (targetClass == null) {
                  break;
                }
                resultList.add(targetClass);
            }
            return resultList;
      } catch (Exception ignore) {
      }
      return Collections.emptyList();
    }

    /**
   * @param clazz 指定的class对象
   * @description 获取指定类的接口及以上父类实现的接口集合(包含当前接口 ( 如果是接口的话)的class对象)
   */
    public static List<Class<?>> getSuperInterfaceList(Class<?> clazz) {
      if (clazz == null) {
            return Collections.emptyList();
      }
      List<Class<?>> resultList = new ArrayList<>();
      if (clazz.isInterface()) {
            resultList.add(clazz);
      }
      if (clazz.getInterfaces().length == 0) {
            return resultList;
      }
      CollUtil.addAll(resultList, clazz.getInterfaces());
      Stream.of(clazz.getInterfaces()).forEach(item -> CollUtil.addAll(resultList, getSuperInterfaceList(item)));
      return resultList.stream().distinct().collect(Collectors.toList());
    }

    /**
   * @param clazz Exception类型的class对象(运行时及编译期)
   * @description 获取传入class对象的父类class对象
   * 如果传入为空或者传入的是Object(所有类的顶层父类)的class对象均返回为空
   */
    public static Class<?> getSuperClass(Class<?> clazz) {
      if (clazz == null || clazz == OBJECT_CLASS || clazz.isInterface()) {
            return null;
      }
      return clazz.getSuperclass();
    }

    /**
   * @param clazz class对象
   * @description 判断传入的class对象是否是接口(interface)
   */
    public static boolean isInterface(Class<?> clazz) {
      if (null == clazz) {
            return false;
      }
      return clazz.isInterface();
    }

    /**
   * @param compareClass    比较类对象
   * @param beComparedClass 被比较类对象
   * @description 比较比较类对象是否属于被比较类对象,或者是否是被比较类对象的子类,子实现类,子抽象类,子接口
   */
    public static boolean equals(Class<?> compareClass, Class<?> beComparedClass) {
      if (null == compareClass || null == beComparedClass) {
            return false;
      }
      List<ClassTypeEnum> classTypeEnumList = ClassUtil.getClassType(beComparedClass);
      if (classTypeEnumList.isEmpty()) {
            return false;
      }
      //基本思路
      // 判断被比较的是类还是注解还是接口还是枚举
      //如果是注解
      //获取当前类上的注解及嵌套注解进行比较
      if (classTypeEnumList.contains(ClassTypeEnum.ANNOTATION)) {
            return ClassUtil.equalsAnnotation(Arrays.asList(compareClass.getAnnotations()), beComparedClass);
      }
      //如果是枚举
      //直接比较,枚举的统一父类都是Enum
      if (classTypeEnumList.contains(ClassTypeEnum.ENUM)) {
            return compareClass == beComparedClass;
      }
      //如果是接口
      //获取当前类实现的接口及嵌套接口进行比较
      if (classTypeEnumList.contains(ClassTypeEnum.INTERFACE)) {
            return ClassUtil.equalsInterface(Arrays.asList(compareClass.getInterfaces()), beComparedClass);
      }
      //其它情况就判断是类
      //获取当前类对象的父以上类进行比较
      return ClassUtil.equalsClass(compareClass, beComparedClass);
    }

    /**
   * @param annotationList注解对象集合
   * @param beComparedClass 被比较的class对象
   * @description 比较注解对象集合中是否含被比较的class对象
   * 此处是【递归】调用实现
   */
    public static boolean equalsAnnotation(List<Annotation> annotationList, Class<?> beComparedClass) {
      if (null == annotationList || annotationList.isEmpty()) {
            return false;
      }
      List<Annotation> subAnnotationList = new ArrayList<>();
      boolean flag = false;
      for (Annotation annotation : annotationList) {
            if (annotation.getClass() == beComparedClass) {
                flag = true;
                break;
            } else {
                subAnnotationList.add(annotation);
            }
      }
      if (!flag) {
            flag = ClassUtil.equalsAnnotation(subAnnotationList, beComparedClass);
      }
      return flag;
    }

    /**
   * @param clazz         类class对象
   * @param beComparedClass 被比较的class对象
   * @description 比较注解对象集合中是否含被比较的class对象
   * 此处是【递归】调用实现
   */
    public static boolean equalsClass(Class<?> clazz, Class<?> beComparedClass) {
      return null != clazz && (clazz == beComparedClass || ClassUtil.equalsClass(clazz.getSuperclass(), beComparedClass));
    }

    /**
   * @param interfaceList   接口class对象集合
   * @param beComparedClass 被比较的class对象
   * @description 比较注解对象集合中是否含被比较的class对象
   * 此处是【递归】调用实现
   */
    public static boolean equalsInterface(List<Class<?>> interfaceList, Class<?> beComparedClass) {
      if (null == interfaceList || interfaceList.isEmpty()) {
            return false;
      }
      List<Class<?>> subInterfaceList = new ArrayList<>();
      boolean flag = false;
      for (Class<?> clazz : interfaceList) {
            if (clazz == beComparedClass) {
                flag = true;
                break;
            } else {
                CollUtil.addAll(subInterfaceList, clazz.getInterfaces());
            }
      }
      if (!flag) {
            flag = ClassUtil.equalsInterface(subInterfaceList, beComparedClass);
      }
      return flag;
    }

    /**
   * @param clazz 类对象
   * @description 判断传入的类对象类型
   */
    public static List<ClassTypeEnum> getClassType(Class<?> clazz) {
      List<ClassTypeEnum> classTypeEnumList = new ArrayList<>();
      if (null == clazz) {
            classTypeEnumList.add(ClassTypeEnum.NULL);
            return classTypeEnumList;
      }
      if (clazz.isInterface()) {
            classTypeEnumList.add(ClassTypeEnum.INTERFACE);
      }
      if (clazz.isEnum()) {
            classTypeEnumList.add(ClassTypeEnum.ENUM);
      }
      if (clazz.isAnnotation()) {
            classTypeEnumList.add(ClassTypeEnum.ANNOTATION);
      }
      if (clazz.isArray()) {
            classTypeEnumList.add(ClassTypeEnum.ARRAY);
      }
      if (clazz.isSynthetic()) {
            classTypeEnumList.add(ClassTypeEnum.SYNTHETIC);
      }
      if (clazz.isAnonymousClass()) {
            classTypeEnumList.add(ClassTypeEnum.SYNTHETIC);
      }
      return classTypeEnumList;
    }

    @Getter
    @AllArgsConstructor
    public enum ClassTypeEnum {

      /**
         * 类
         */
      CLASS,

      /**
         * 接口
         */
      INTERFACE,

      /**
         * 枚举
         */
      ENUM,

      /**
         * 注解
         */
      ANNOTATION,

      /**
         * 其它类型
         */
      OTHER,

      /**
         * 空对象 无法识别
         */
      NULL,

      /**
         * 数组
         */
      ARRAY,

      /**
         * 合成类
         */
      SYNTHETIC,

      /**
         * 匿名类
         */
      ANONYMOUS,

      ;

    }

}
```

S17Ly 发表于 2023-7-24 14:43

public enum ClassUtil {

    ;

    /**
   * 最多循环次数的极限值
   */
注释的”循环次数极限值” 这里都没有定义,是我学的不够还是说这样也行?

huangnzd 发表于 2023-7-24 11:25

支持一下,试试能不能用

不知道改成啥 发表于 2023-7-24 11:26

你这public enum ClassUtil不对吧这样才正常啊public class ClassUtil

鹿鸣 发表于 2023-7-24 11:44

我也去试一下,代码还需要排版下

kenxy 发表于 2023-7-24 12:00

感谢楼主分享,虽然我不懂

jgylll 发表于 2023-7-24 23:40

楼主技术可以,学习了

shanyepifu 发表于 2023-7-25 09:50

tanzhiwei 发表于 2023-7-24 11:26
你这public enum ClassUtil不对吧这样才正常啊public class ClassUtil

怕是想使用枚举类,实现天然的单例吧。。。

不知道改成啥 发表于 2023-7-25 11:17

shanyepifu 发表于 2023-7-25 09:50
怕是想使用枚举类,实现天然的单例吧。。。

好奇怪的想法

KamisatoAyaka 发表于 2023-7-25 17:25

Util咋是枚举型的
页: [1] 2
查看完整版本: class工具类-获取上级类或者接口集