Differencebetween Getfields and Getdeclaredfields in Java Reflection

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



Leave a reply



Submit