java 值 继承,使用Java Reflection检索继承的属性名称/值

使用Java Reflection检索继承的属性名称/值

我是一个Java对象' ChildObj' 这是从'ParentObj'扩展而来的。 现在,如果可以使用Java反射机制检索ChildObj的所有属性名称和值,包括继承的属性?

Class.getFields为我提供了公共属性数组,Class.getDeclaredFields为我提供了所有字段的数组,但它们都没有包含继承的字段列表。

有没有办法检索继承的属性呢?

12个解决方案

155 votes

不,你需要自己写。 它是一个在Class.getSuperClass()上调用的简单递归方法:

public static List getAllFields(List 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(), LinkedList.class));

}

dfa answered 2019-07-08T21:36:36Z

77 votes

public static List getAllFields(Class> type) {

List fields = new ArrayList();

for (Class> c = type; c != null; c = c.getSuperclass()) {

fields.addAll(Arrays.asList(c.getDeclaredFields()));

}

return fields;

}

Esko Luontola answered 2019-07-08T21:36:52Z

32 votes

如果你想依靠一个库来完成这个,那么Apache Commons Lang版本3.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 allFields = FieldUtils.getAllFieldsList(LinkedList.class);

// Get the fields form each individual class in the type's hierarchy

final List allFieldsClass = Arrays.asList(LinkedList.class.getFields());

final List allFieldsParent = Arrays.asList(AbstractSequentialList.class.getFields());

final List allFieldsParentsParent = Arrays.asList(AbstractList.class.getFields());

final List 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));

}

}

Chris answered 2019-07-08T21:37:16Z

6 votes

你需要打电话:

Class.getSuperclass().getDeclaredFields()

根据需要递归继承层次结构。

Nick Holt answered 2019-07-08T21:37:46Z

5 votes

使用思考库:

public Set getAllFields(Class> aClass) {

return org.reflections.ReflectionUtils.getAllFields(aClass);

}

Lukasz Ochmanski answered 2019-07-08T21:38:10Z

3 votes

递归解决方案是可以的,唯一的小问题是它们返回已声明和继承成员的超集。 请注意,getDeclaredFields()方法也返回私有方法。 因此,只要您导航整个超类层次结构,您将包含在超类中声明的所有私有字段,并且那些不会被继承。

一个带Modifier.isPublic ||的简单过滤器 Modifier.isProtected谓词会做:

import static java.lang.reflect.Modifier.isPublic;

import static java.lang.reflect.Modifier.isProtected;

(...)

List inheritableFields = new ArrayList();

for (Field field : type.getDeclaredFields()) {

if (isProtected(field.getModifiers()) || isPublic(field.getModifiers())) {

inheritableFields.add(field);

}

}

Marek Dec answered 2019-07-08T21:38:41Z

2 votes

private static void addDeclaredAndInheritedFields(Class> c, Collection fields) {

fields.addAll(Arrays.asList(c.getDeclaredFields()));

Class> superClass = c.getSuperclass();

if (superClass != null) {

addDeclaredAndInheritedFields(superClass, fields);

}

}

" DidYouMeanThatTomHa ..."的工作版本 解决方案如上

Theo Platt answered 2019-07-08T21:39:05Z

1 votes

你可以试试:

Class parentClass = getClass().getSuperclass();

if (parentClass != null) {

parentClass.getDeclaredFields();

}

Manuel Selva answered 2019-07-08T21:39:23Z

1 votes

更短,更少的对象实例化?^^

private static Field[] getAllFields(Class> type) {

if (type.getSuperclass() != null) {

return (Field[]) ArrayUtils.addAll(getAllFields(type.getSuperclass()), type.getDeclaredFields());

}

return type.getDeclaredFields();

}

Alexis LEGROS answered 2019-07-08T21:39:47Z

0 votes

private static void addDeclaredAndInheritedFields(Class c, Collection fields) {

fields.addAll(Arrays.asList(c.getDeclaredFields()));

Class superClass = c.getSuperclass();

if (superClass != null) {

addDeclaredAndInheritedFields(superClass, fields);

}

}

DidYouMeanThatTomHawtin answered 2019-07-08T21:40:04Z

0 votes

这是@ user1079877接受的答案的重写。 它可能是一个不修改函数参数的版本,也使用了一些现代Java特性。

public Field[] getFields(final Class type, final Field... fields) {

final Field[] items = Stream.of(type.getDeclaredFields(), fields).flatMap(Stream::of).toArray(Field[]::new);

if (type.getSuperclass() == null) {

return items;

} else {

return getFields(type.getSuperclass(), items);

}

}

此实现还使调用更简洁:

var fields = getFields(MyType.class);

scrutari answered 2019-07-08T21:40:34Z

0 votes

我最近在org.apache.commons.lang3.reflect.FieldUtils中看到了这段代码

public static List getAllFieldsList(final Class> cls) {

Validate.isTrue(cls != null, "The class must not be null");

final List allFields = new ArrayList<>();

Class> currentClass = cls;

while (currentClass != null) {

final Field[] declaredFields = currentClass.getDeclaredFields();

Collections.addAll(allFields, declaredFields);

currentClass = currentClass.getSuperclass();

}

return allFields;

}

aman answered 2019-07-08T21:40:58Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值