Thursday, December 23, 2021

Reflection in Java - Getting Field Information

Reflection in Java-class gives a good idea about how class is an entry point to all the Reflection APIs. Once you have Class object you can get information about members of the class fields, constructors, methods. In this post we'll see how to get information about class fields using Java reflection API.

Class fields have a type and a value, the java.lang.reflect.Field class provides methods for accessing type information, field’s modifier and setting and getting values of a field on a given object.


Member Interface in Java Reflection API

With in the Reflection hierarchy an interface java.lang.reflect.Member is defined which is implemented by java.lang.reflect.Field, java.lang.reflect.Method, and java.lang.reflect.Constructor. Thus Member is an interface that reflects identifying information about a single member (a field or a method) or a constructor.

How to get Field object using reflection

There are 4 methods for getting fields of the class.

  • getField(String name)- Returns a Field object that reflects the specified public member field of the class or interface represented by this Class object.
  • getFields()- Returns an array containing Field objects reflecting all the accessible public fields of the class or interface represented by this Class object.
  • getDeclaredField(String name)- Returns a Field object that reflects the specified declared field of the class or interface represented by this Class object.
  • getDeclaredFields()- Returns an array of Field objects reflecting all the fields declared by the class or interface represented by this Class object.

So getFields() methods will only return object for public fields where as getDeclaredField() methods will return all the fields.

Getting field information using Java reflection example

In this example generic class ReflectField is used which has few fields with access modifier as public or private.

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;

public class ReflectField<T> {
  public String name = "Test";
  private int i = 10;
  public List<Integer> numList;
  public T val;
     
  public static void main(String arg[]){
    try {
      Class<?> c = Class.forName("org.netjs.prog.ReflectField");
      try {
        Field f = c.getField("name");
        System.out.println("Name field " + f.getName());
      
        Field[] fields = c.getFields();
        System.out.println("All Fields - " + Arrays.toString(fields));
        
        fields = c.getDeclaredFields();      
        System.out.println("Declared Fields - " + Arrays.toString(fields));
      } catch (NoSuchFieldException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }    
    }catch (ClassNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}

Output

Name field name

All Fields - [public java.lang.String org.netjs.prog.ReflectField.name, public java.util.List org.netjs.prog.ReflectField.numList, 
public java.lang.Object org.netjs.prog.ReflectField.val]

Declared Fields - [public java.lang.String org.netjs.prog.ReflectField.name, private int org.netjs.prog.ReflectField.i, 
public java.util.List org.netjs.prog.ReflectField.numList, public java.lang.Object org.netjs.prog.ReflectField.val]

You can see here getFields() return array of all public fields in the class where as getDeclaredFields() return all the fields (field i is having access modifier as private).

Getting field type using reflection

If you want to know the types of fields in any class using Java reflection API you can do it using the methods getType() and getGenericType().

Class<?> c = Class.forName("org.netjs.prog.ReflectField");
fields = c.getDeclaredFields();
for(Field field : fields){
  System.out.println("Field name - " + field.getName() 
      + " has Field Type " + field.getType());
  System.out.println("Field name - " + field.getName() 
      + " has Generic Field Type " + field.getGenericType());
}

Output

Field name - name has Field Type class java.lang.String
Field name - name has Generic Field Type class java.lang.String
Field name - i has Field Type int
Field name - i has Generic Field Type int
Field name - numList has Field Type interface java.util.List
Field name - numList has Generic Field Type java.util.List<java.lang.Integer>
Field name - val has Field Type class java.lang.Object
Field name - val has Generic Field Type T

Here notice that the type for the field val is displayed as java.lang.Object because generics are implemented via type erasure which removes all information regarding generic types during compilation. Thus T is replaced by the upper bound of the type variable, in this case, java.lang.Object.

Getting field modifiers using reflection

You can get the field modifiers by using the getModifiers() method. This method returns the Java language modifiers for the field represented by this Field object, as an integer. The Modifier class should be used to decode the modifiers.

Class<?> c = Class.forName("org.netjs.prog.ReflectField");
fields = c.getDeclaredFields();
for(Field field : fields){     
    System.out.println("Field name - " + field.getName() + " has modifier " 
       + Modifier.toString(field.getModifiers()));
}

Output

Field name - name has modifier public
Field name - i has modifier private
Field name - numList has modifier public
Field name - val has modifier public

Getting and Setting Field Values using reflection

If you have an object of a class, using Java reflection API you can set the values of fields in that class. This is typically done only in special circumstances when setting the values in the usual way is not possible. Because such access usually violates the design intentions of the class, it should be used with the utmost discretion.

Given a public field name which is of type String here the new value is set to the field name.

public String name = "Test";
Class<?> c = Class.forName("org.netjs.prog.ReflectField");
ReflectField rf = new ReflectField();
Field f = c.getField("name");
// getting the field value
System.out.println("Value of field name " + f.get(rf));
// setting the new field value
f.set(rf, "New Value");
System.out.println("Value of field name " + rf.name);

Output

Value of field name Test
Value of field name New Value

That's all for this topic Reflection in Java - Getting Field Information. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Advanced Tutorial Page


Related Topics

  1. Java Reflection API Tutorial
  2. Reflection in Java - Getting Class Information
  3. Invoking Getters And Setters Using Reflection in Java
  4. Java Object Cloning - clone() Method
  5. Serialization and Deserialization in Java

You may also like-

  1. Java Nested Class And Inner Class
  2. Serialization Proxy Pattern in Java
  3. How to Pass Command Line Arguments in Eclipse
  4. Try-With-Resources in Java With Examples
  5. Type Casting in Java With Conversion Examples
  6. Lambda Expressions in Java 8
  7. Optional Class in Java With Examples
  8. ConcurrentHashMap in Java With Examples