Get all Fields of class hierarchy [duplicate]

2020-04-16 02:48发布

I have classes:

ClassA{
 public String filedA;
}

ClassB extends ClassA{
 public String filedB;
}

ClassC extends ClassB{
 public String filedC;
}

Then I create object:

ClassC c=new ClassC();
c.fieldC="TestC";
c.fieldA="TestA";
c.fieldB="TestB";

After I try get all fields, I call

Field[] fields=c.getClass().getDeclaredFields();

But I get array with only one item

fields[fieldC]

How to get all fields from all classes include extends?

6条回答
叛逆
2楼-- · 2020-04-16 02:58

Your C class does not extend any class. Then, getDeclaredFields() only returns String filedC as you have seen. You cannot do c.fieldA="TestA" and c.fieldB="TestB" because your class does not declare this fields. Anyway, in case of C extends B and B extends A, method getFields() returns only public fields (including inherited):

Returns an array containing Field objects reflecting all the accessible public fields of the class or interface represented by this Class object.

And getDeclaredFields() returns all fields declared in the class (not including inherited):

Returns an array of Field objects reflecting all the fields declared by the class or interface represented by this Class object. This includes public, protected, default (package) access, and private fields, but excludes inherited fields.

查看更多
在下西门庆
3楼-- · 2020-04-16 02:59

Try the following:

Field[] fields = c.getClass().getFields();

If you want all superclass fields, see the following:

Retrieving the inherited attribute names/values using Java Reflection

查看更多
走好不送
4楼-- · 2020-04-16 03:02

If you don't want to reinvent the wheel you could rely upon Apache Commons Lang version 3.2+ which provides 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));
    }
}
查看更多
走好不送
5楼-- · 2020-04-16 03:03

getDeclaredFields() which you are using, are not contain inherited flields from superclass.

if you want all clields just use getFields() method

查看更多
乱世女痞
6楼-- · 2020-04-16 03:05

This would work with reflection if ClassC derived from ClassB (and presumably from ClassA etc..). I assume this is a typo ? Then this:

Field[] fields = c.getClass().getFields();

would work as expected.

查看更多
爱情/是我丢掉的垃圾
7楼-- · 2020-04-16 03:15

You should be able to get them with

Field[] fields = c.getClass().getFields();

This returns all accessible fields.

查看更多
登录 后发表回答