java获取类所有字段,以及字段的字段的类型

返回
Author Avatar
钢翼
2021-03-10
编程
108

    /**
     * 获取类的所有字段,包括父类
     *
     * @param baseClazz
     * @param <T>
     * @return
     */
    public static <T> List<Field> getAllFields(Class<T> baseClazz) {
        Class clazz = baseClazz;

        ArrayList fieldList;
        for (fieldList = new ArrayList(); clazz != null; clazz = clazz.getSuperclass()) {
            fieldList.addAll(new ArrayList(Arrays.asList(clazz.getDeclaredFields())));
        }

        return fieldList;
    }

    /**
     * 判断类型是否java内置类型
     * 只要返回true则不会遍历该类型里面的字段,即此方法返回true则为底层类型
     *
     * @param type
     * @return
     */
    public static boolean isJavaInnerType(Type type) {
        if (type instanceof ParameterizedType) {
            return false;
        }
        Class<?> clazz = (Class<?>) type;
        if (clazz.isPrimitive()) {
            return true;
        } else if (clazz.isEnum()) {
            return true;
        }

        return (clazz.getName().startsWith("java.math")|| clazz.getName().startsWith("java.lang") || clazz.getName().startsWith("java.util.Date") || clazz.getName().startsWith("java.time"));


    }

    /**
     * 获取所有字段类型,包括字段的字段
     *
     * @param set
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> Set<Type> getAllClasses(Set<Type> set, Type clazz) {
        if (set == null) {
            set = new HashSet<>();
        }
        if (isJavaInnerType(clazz)) {
            set.add(clazz);
        } else if (clazz instanceof ParameterizedType) {
            for (Type type : ((ParameterizedTypeImpl) clazz).getActualTypeArguments()) {
                if (!set.contains(type)) {
                    set.add(type);
                    getAllClasses(set, type);
                }
            }
        } else if (((Class<?>) clazz).isArray()) {

            getAllClasses(set, ((Class<?>) clazz).getComponentType());

        } else {
            List<Field> fields = getAllFields((Class<?>) clazz);
            for (Field field : fields) {
                if (isJavaInnerType(field.getType())) {
                    set.add(field.getType());
                } else if (field.getGenericType() != null && field.getGenericType() instanceof ParameterizedType) {
                    set.add(field.getGenericType());
                    ParameterizedType pt = (ParameterizedType) field.getGenericType();
                    for (Type type : pt.getActualTypeArguments()) {
                        if (!set.contains(type)) {
                            set.add(type);
                            getAllClasses(set, type);
                        }
                    }
                }else if(field.getGenericType()!=null && field.getGenericType() instanceof GenericArrayType){
                    set.add(field.getGenericType());
                    ParameterizedType pt = (ParameterizedType) ((GenericArrayType) field.getGenericType()).getGenericComponentType();
					set.add(pt);
                    for (Type type : pt.getActualTypeArguments()) {
                        if (!set.contains(type)) {
                            set.add(type);
                            getAllClasses(set, type);
                        }
                    }
                }
                else if (field.getType().isArray()) {
                    set.add(field.getType());
                    getAllClasses(set, field.getType().getComponentType());

                } else {
                    if (!set.contains(field.getType())) {
                        set.add(field.getType());
                        getAllClasses(set, field.getType());
                    }
                }
            }

        }
        return set;
    }

调用

     @Data
    public static class A{
        private List<Long> a1;
        private Map<String,Integer> a2;
        private List<B> a3;
        private B[] a4;
        private int[] a5;
		private List<Map<String, Long>>[] a6;
		private BigInteger  a7;
    }
    @Data
    public static class B{

        private int b1;
        private Integer b2;
        private String b3;
        private Date b4;
        private LocalDate b5;
        private LocalDateTime b6;
        private  A b7;
		private Map<List<Map<List<Long>, A>>, A> b8;
    }
    @Test
    public void test() {
        System.out.println(getAllClasses(null, A.class));
    }