What is the difference between getFields and getDeclaredFields in Java reflection
getFields()
All the public
fields up the entire class hierarchy.
getDeclaredFields()
All the fields, regardless of their accessibility but only for the current class, not any base classes that the current class might be inheriting from.
To get all the fields up the hierarchy, I have written the following function:
public static Iterable<Field> getFieldsUpTo(@Nonnull Class<?> startClass,
@Nullable Class<?> exclusiveParent) {
List<Field> currentClassFields = Lists.newArrayList(startClass.getDeclaredFields());
Class<?> parentClass = startClass.getSuperclass();
if (parentClass != null &&
(exclusiveParent == null || !(parentClass.equals(exclusiveParent)))) {
List<Field> parentClassFields =
(List<Field>) getFieldsUpTo(parentClass, exclusiveParent);
currentClassFields.addAll(parentClassFields);
}
return currentClassFields;
}
The exclusiveParent
class is provided to prevent the retrieval of fields from Object
. It may be null
if you DO want the Object
fields.
To clarify, Lists.newArrayList
comes from Guava.
Update
FYI, the above code is published on GitHub in my LibEx project in ReflectionUtils.
Why I can't access to field class using reflection?
My question is why is the "name" field not found?
The getField
method does not return private fields. You need to use getDeclaredField
to get a private field. But getDeclaredField
only returns fields for the target class.
So to find and update a private field (in the given class) you need to do something like this:
Field field = User.class.getDeclaredField("name");
field.setAccessible(true);
field.set(userObject, value);
(Notice that you also need to use setAccessible
to allow access to a private field.)
If you wanted to set a named private field in some superclass of a given class, you would need to use getSuperclass()
to traverse the superclass chain until you found the Class
that has the field you are looking for.
Retrieving the inherited attribute names/values using Java Reflection
no, you need to write it yourself. It is a simple recursive method called on 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));
}
Why ClassName.class.getFields() returns only public fields?
Purpose of getFields
is to return all public fields available via class, including inherited ones.
If you are looking for list of fields declared in this class use getDeclaredFields
.
What is the difference between getFields and getDeclaredFields in Java reflection
getFields()
All the public
fields up the entire class hierarchy.
getDeclaredFields()
All the fields, regardless of their accessibility but only for the current class, not any base classes that the current class might be inheriting from.
To get all the fields up the hierarchy, I have written the following function:
public static Iterable<Field> getFieldsUpTo(@Nonnull Class<?> startClass,
@Nullable Class<?> exclusiveParent) {
List<Field> currentClassFields = Lists.newArrayList(startClass.getDeclaredFields());
Class<?> parentClass = startClass.getSuperclass();
if (parentClass != null &&
(exclusiveParent == null || !(parentClass.equals(exclusiveParent)))) {
List<Field> parentClassFields =
(List<Field>) getFieldsUpTo(parentClass, exclusiveParent);
currentClassFields.addAll(parentClassFields);
}
return currentClassFields;
}
The exclusiveParent
class is provided to prevent the retrieval of fields from Object
. It may be null
if you DO want the Object
fields.
To clarify, Lists.newArrayList
comes from Guava.
Update
FYI, the above code is published on GitHub in my LibEx project in ReflectionUtils.
Java reflection - Get a class variable by passing the name
You probably don't want to do this. But okay,
You compare strings and other well defined objects like this:
boolean b = java.lang.Objects.equals(a, b)
Additionally getFields
provides only public fields. See What is the difference between getFields and getDeclaredFields in Java reflection
Aside: try not to return null. Prefer java.lang.Optional<T>
or throw an exception
Comparing field values using reflection
You might check out org.apache.commons.lang.builder.EqualsBuilder which will save you a lot of this hassle if you're wanting to do a field by field comparison.
org.apache.commons.lang.builder.EqualsBuilder.reflectionEquals(Object, Object)
If you're wanting to compare fields yourself, check out java.lang.Class.getDeclaredFields()
which will give you all the fields including non-public fields.
To compare the value of the fields use f.get(qa).equals(f.get(qa4))
Currently, you are actually comparing the field instances and not the values.
Java Reflection: Getting fields and methods in declaration order
With jdk 6, the reflected fields are in deed in their declaration order. In early jdk that wasn't the case. Apparently enough people have nagged.
Although not guaranteed by javadoc, I would still take this order as granted, and I assume the order will be kept in future jdks too.
In your app, like in most apps, the dependency on the declaration order is mostly vanity - your app won't fail if the order screws up, it just become a little uglier.
Related Topics
Is This the Best Way to Rewrite the Content of a File in Java
Peer Not Authenticated While Importing Gradle Project in Eclipse
Cannot Create Jdbc Driver of Class ' ' for Connect Url 'Null':I Do Not Understand This Exception
How to Parse a JSON String to an Array Using Jackson
Checking for a Null Int Value from a Java Resultset
How to Bind an Object List with Thymeleaf
How to Update an Entity Using Spring-Data-Jpa
Why Can Final Object Be Modified
How to Remove a Key from Hashmap While Iterating Over It
Writing a Large Resultset to an Excel File Using Poi
Could Not Find Method Compile() for Arguments Gradle
Performance Considerations for Keyset() and Entryset() of Map
Why Are the Level.Fine Logging Messages Not Showing