结论:
getDeclaredField(s)与getField(s)的主要区别在于对父子类字段及不同访问权限修饰的字段的获取上.
-
getDeclaredFields / getDeclaredField :
(1) 能获取到本类的所有字段(包括 private, default, protected, public ), 不能获取到父类的任何字段
(2) 在(1)的基础上, 该字段可以是同时被 static, final, volatile, transient 中的一种或几种修饰 -
getFields / getField :
(1) 能且仅能获取到本类及所有父类/超类中 public 权限的字段
(2) 在(1)的基础上, 该字段可以是同时被 static, final, volatile, transient 中的一种或几种修饰
示例:
/**
* 父类
*/
public class SuperObject {
private int superA;
int superB;
protected int superC;
public int superD;
}
/**
* 本类
*/
public class SubObject extends SuperObject {
private int subA;
int subB;
protected int subC;
public int subD;
}
/**
* 测试打印
*/
public static void main(String[] args) throws NoSuchFieldException {
Field[] declaredFields = SubObject.class.getDeclaredFields();
Arrays.stream(declaredFields).forEach(System.out::println);
System.out.println("----------");
Field[] fields = SubObject.class.getFields();
Arrays.stream(fields).forEach(System.out::println);
}
打印结果:
private int com.test.SubObject.subA
int com.test.SubObject.subB
protected int com.test.SubObject.subC
public int com.test.SubObject.subD
----------
public int com.test.SubObject.subD
public int com.test.SuperObject.superD
扩展:
如何获取本类(private, default, protected, public)及父类/超类(private, default, protected, public)的所有字段? 可自定义如下方法:
/**
* 反射获取本类及所有父类的字段(包含所有权限)
*/
public static List<Field> getAllFields(Class<?> clazz) {
List<Field> fieldList = new ArrayList<>();
while (clazz != null) {
fieldList.addAll(Arrays.stream(clazz.getDeclaredFields()).collect(Collectors.toList()));
clazz = clazz.getSuperclass();
}
return fieldList;
}

174

被折叠的 条评论
为什么被折叠?



