January 26, 2023

Java Reflection – Class Fields

Using Java Reflection you can get information about the class fields and get and set field values at run time. In Java Reflection API there is a class java.lang.reflect.Field that has methods for accessing field's type, field’s modifier and setting and getting values of a field.

Getting Field instance

First thing is to get the instance of Field class for that you will have to use methods of the java.lang.Class as that class is the entry point for all reflection operations.

There are 4 methods for getting field instance-

  1. getField(String name)- Returns a Field object representing the public member field of the class or interface.
  2. getFields()- Returns an array containing Field objects reflecting all the accessible public fields of the class or interface.
  3. getDeclaredField(String name)- Returns a Field object that reflects the specified declared field (even private) of the class or interface represented by this Class object.
  4. getDeclaredFields()- 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.

Getting information about class fields – Java example

This example shows how to get information like type, modifier of individual/all fields of a class. Methods of the Field class used are-

  • getType() method of the Field class returns the declared type for the field.
  • getModifiers() method of the field class returns the modifiers for the field as an integer.
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Set;

public class FieldReflectionDemo {
  public String str = "Reflection";
  private int i;
  public boolean flag = false;
  public Set<String> citySet;
    
  public static void main(String[] args) {
    try {
      FieldReflectionDemo obj = new FieldReflectionDemo();
      Class<?> c = obj.getClass();
      // get specific field
      Field f = c.getField("str");
      // getting field type
      Class<?> type = f.getType();
      // getting field modifiers
      int mod = f.getModifiers();
      System.out.println("Field name - " + f.getName()); 
      System.out.println("Field type - " + type.getName());
      System.out.println("Field modifiers - " + Modifier.toString(mod));
      System.out.println("--- Getting all fields ---");
      Field[] fields = c.getDeclaredFields();
      for(Field field : fields) {
        System.out.println("Field name - " + field.getName()); 
        System.out.println("Field type - " + field.getType());
        System.out.println("Field modifiers - " + Modifier.toString(field.getModifiers()));
      }        
    } catch (NoSuchFieldException | SecurityException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}
Output
Field name - str
Field type - java.lang.String
Field modifiers - public
--- Getting all fields ---
Field name - str
Field type - class java.lang.String
Field modifiers - public
Field name - i
Field type - int
Field modifiers - private
Field name - flag
Field type - boolean
Field modifiers - public
Field name - citySet
Field type - interface java.util.Set
Field modifiers - public

Getting and setting values

For getting value there is get(Object obj) method which returns the value of the field represented by this Field, on the specified object.

For Setting value there is set(Object obj, Object value) method which sets the field represented by this Field object on the specified object argument to the specified new value.

import java.lang.reflect.Field;
import java.util.Set;

public class FieldReflectionDemo {
  public String str = "Reflection";
  private int i;
  public boolean flag = false;
  public Set<String> citySet;
    
  public static void main(String[] args) {
    try {
      FieldReflectionDemo obj = new FieldReflectionDemo();
      Class<?> c = obj.getClass();
      // get specific field
      Field f = c.getField("str");
      // show value - get method
      System.out.println("Field name- " + f.getName() + " Value- " + f.get(obj));
      // set new value
      f.set(obj, "New Value");
      System.out.println("Field name- " + f.getName() + " Value- " + f.get(obj));        
    } catch (IllegalAccessException | NoSuchFieldException | SecurityException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}
Output
Field name- str Value- Reflection
Field name- str Value- New Value

Getting and setting value of a private field

You can even set value of a private field using Reflection. For that you need to set the accessible as true using setAccesssible() method.

In the example we have a class Access with one private int field i. In FieldReflectionDemo class we’ll access this field using reflection and set a value to it. If you don’t set the accessible flag using setAccesssible() method it will throw IllegalAccessException as shown below.

class Access{
  private int i;
}

public class FieldReflectionDemo {
  public String str = "Reflection";
  public boolean flag = false;
  public Set<String> citySet;
    
  public static void main(String[] args) {
    try {
      Access obj = new Access();
      Class<?> c = obj.getClass();
      // get specific field
      Field f = c.getDeclaredField("i");
      // show value - get method
      System.out.println("Field name- " + f.getName() + " Value- " + f.get(obj));
      // set new value
      f.set(obj, 7);
      System.out.println("Field name- " + f.getName() + " Value- " + f.get(obj));       
    } catch (IllegalAccessException | NoSuchFieldException | SecurityException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}
Output
java.lang.IllegalAccessException: class com.knpcode.programs.FieldReflectionDemo cannot access a member of class com.knpcode.programs.Access with modifiers "private"

Run again after making this change and you will be able to access even the private fields.

Field f = c.getDeclaredField("i");
f.setAccessible(true);
Output
Field name- i Value- 0
Field name- i Value- 7

Reference: https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/reflect/Field.html

That's all for the topic Java Reflection – Class Fields. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment