使用 Java 反射检索继承的属性名称/值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1042798/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Retrieving the inherited attribute names/values using Java Reflection
提问by Veera
I've a Java object 'ChildObj' which is extended from 'ParentObj'. Now, if it is possible to retrieve all the attribute names and values of ChildObj, including the inherited attributes too, using Java reflection mechanism?
我有一个从 'ParentObj' 扩展的 Java 对象 'ChildObj'。现在,是否可以使用 Java 反射机制检索 ChildObj 的所有属性名称和值,包括继承的属性?
Class.getFieldsgives me the array of public attributes, and Class.getDeclaredFieldsgives me the array of all fields, but none of them includes the inherited fields list.
Class.getFields为我提供了公共属性数组,而Class.getDeclaredFields为我提供了所有字段的数组,但它们都不包含继承的字段列表。
Is there any way to retrieve the inherited attributes also?
有没有办法检索继承的属性?
采纳答案by dfa
no, you need to write it yourself. It is a simple recursive method called on Class.getSuperClass():
不,你需要自己写。这是一个在Class.getSuperClass()上调用的简单递归方法:
public static List<Field> getAllFields(List<Field> fields, Class<?> type) {
fields.addAll(Arrays.asList(type.getDeclaredFields()));
if (type.getSuperclass() != null) {
getAllFields(fields, type.getSuperclass());
}
return fields;
}
@Test
public void getLinkedListFields() {
System.out.println(getAllFields(new LinkedList<Field>(), LinkedList.class));
}
回答by Nick Holt
You need to call:
您需要致电:
Class.getSuperclass().getDeclaredFields()
Recursing up the inheritance hierarchy as necessary.
根据需要递归继承层次结构。
回答by Manuel Selva
You can try:
你可以试试:
Class parentClass = getClass().getSuperclass();
if (parentClass != null) {
parentClass.getDeclaredFields();
}
回答by DidYouMeanThatTomHawtin
private static void addDeclaredAndInheritedFields(Class c, Collection<Field> fields) {
fields.addAll(Arrays.asList(c.getDeclaredFields()));
Class superClass = c.getSuperclass();
if (superClass != null) {
addDeclaredAndInheritedFields(superClass, fields);
}
}
回答by Esko Luontola
public static List<Field> getAllFields(Class<?> type) {
List<Field> fields = new ArrayList<Field>();
for (Class<?> c = type; c != null; c = c.getSuperclass()) {
fields.addAll(Arrays.asList(c.getDeclaredFields()));
}
return fields;
}
回答by Theo Platt
private static void addDeclaredAndInheritedFields(Class<?> c, Collection<Field> fields) {
fields.addAll(Arrays.asList(c.getDeclaredFields()));
Class<?> superClass = c.getSuperclass();
if (superClass != null) {
addDeclaredAndInheritedFields(superClass, fields);
}
}
Working version of "DidYouMeanThatTomHa..." solution above
上面“DidYouMeanThatTomHa...”解决方案的工作版本
回答by Marek Dec
The recursive solutions are OK, the only small issue is that they return a superset of declared and inherited members. Note that getDeclaredFields() method returns also private methods. So given that you navigate the whole superclass hierarchy you will include all private fields declared in the superclasses, and those don't get inherited.
递归解决方案是可以的,唯一的小问题是它们返回声明和继承成员的超集。请注意, getDeclaredFields() 方法也返回私有方法。因此,考虑到您在整个超类层次结构中导航,您将包括在超类中声明的所有私有字段,而那些不会被继承。
A simple filter with a Modifier.isPublic || Modifier.isProtected predicate would do:
带有 Modifier.isPublic || 的简单过滤器 Modifier.isProtected 谓词会做:
import static java.lang.reflect.Modifier.isPublic;
import static java.lang.reflect.Modifier.isProtected;
(...)
List<Field> inheritableFields = new ArrayList<Field>();
for (Field field : type.getDeclaredFields()) {
if (isProtected(field.getModifiers()) || isPublic(field.getModifiers())) {
inheritableFields.add(field);
}
}
回答by Chris
If instead you wanted to rely upon a library to accomplish this, Apache Commons Langversion 3.2+ provides FieldUtils.getAllFieldsList
:
相反,如果您想依靠库来完成此操作,Apache Commons Lang3.2+ 版提供FieldUtils.getAllFieldsList
:
import java.lang.reflect.Field;
import java.util.AbstractCollection;
import java.util.AbstractList;
import java.util.AbstractSequentialList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.junit.Assert;
import org.junit.Test;
public class FieldUtilsTest {
@Test
public void testGetAllFieldsList() {
// Get all fields in this class and all of its parents
final List<Field> allFields = FieldUtils.getAllFieldsList(LinkedList.class);
// Get the fields form each individual class in the type's hierarchy
final List<Field> allFieldsClass = Arrays.asList(LinkedList.class.getFields());
final List<Field> allFieldsParent = Arrays.asList(AbstractSequentialList.class.getFields());
final List<Field> allFieldsParentsParent = Arrays.asList(AbstractList.class.getFields());
final List<Field> allFieldsParentsParentsParent = Arrays.asList(AbstractCollection.class.getFields());
// Test that `getAllFieldsList` did truly get all of the fields of the the class and all its parents
Assert.assertTrue(allFields.containsAll(allFieldsClass));
Assert.assertTrue(allFields.containsAll(allFieldsParent));
Assert.assertTrue(allFields.containsAll(allFieldsParentsParent));
Assert.assertTrue(allFields.containsAll(allFieldsParentsParentsParent));
}
}
回答by Alexis LEGROS
Shorter and with less object instantiated ? ^^
更短且实例化的对象更少?^^
private static Field[] getAllFields(Class<?> type) {
if (type.getSuperclass() != null) {
return (Field[]) ArrayUtils.addAll(getAllFields(type.getSuperclass()), type.getDeclaredFields());
}
return type.getDeclaredFields();
}
回答by Lukasz Ochmanski
Use Reflections library:
使用反射库:
public Set<Field> getAllFields(Class<?> aClass) {
return org.reflections.ReflectionUtils.getAllFields(aClass);
}