Get all Fields of class hierarchy [duplicate]

2020-04-16 02:31发布

问题:

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?

回答1:

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



回答2:

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:

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));
    }
}


回答4:

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.



回答5:

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

if you want all clields just use getFields() method



回答6:

You should be able to get them with

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

This returns all accessible fields.