This question already has answers here:
Closed 11 months ago.
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?
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
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.
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));
}
}
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.
getDeclaredFields()
which you are using, are not contain inherited flields from superclass.
if you want all clields just use getFields()
method
You should be able to get them with
Field[] fields = c.getClass().getFields();
This returns all accessible fields.