java获取类所有字段,以及字段的字段的类型
钢翼
编程
/**
* 获取类的所有字段,包括父类
*
* @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));
}