Java Reflection for Fields

1. Overview

A field may be either of primitive or reference type. There are eight primitive types: boolean, byte, short, int, long, char, float, and double. A reference type is anything that is a direct or indirect subclass of java.lang.Object including interfacesarrays, and enumerated types.
Reflection API provides several methods to analyze Class fields and modify their values at runtime, in this guide, we will look into some of the commonly used reflection functions for methods.

The source code for this post is available on GitHub.

The below class diagram shows a list of Reflection APIs offered by java.lang.reflect.Field class.
Java Reflection for Fields

2. Reflection for Field API Example

  • Get All Public Fields
  • Get Public Field
  • Field Declaring Class
  • Get Field Type
  • Get/Set Public Field Value
  • Get/Set Private Field Value
Let's first create User.java class and then apply Reflection Method API on it.

User.java

package com.javaguides.reflection.fields;

public class User {
    public int id;
    private String name;
 
    public User(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
     this.name = name;
    }
}

2.1 Get All Public Fields

getFields() method returns the array of public fields of the class including public fields of it’s super classes and super interfaces.
Class<?> concreteClass = Class.forName("com.javaguides.reflection.classes.ConcreteClass");
Field[] fields = concreteClass.getFields();
for (Field field : fields) {
    System.out.println(field.getName());
}
Output:
id

2.2 Get Public Field

Reflection API also provides a method to get a specific public field of a class through getField()method. This method looks for the field in the specified class reference and then in the super interfaces and then in the superclasses.
Class<?> concreteClass = Class.forName("com.javaguides.reflection.fields.User");
Field field = concreteClass.getField("id");
System.out.println(field.getName());
Output:
id

2.3 Field Declaring Class

We can use getDeclaringClass() of field object to get the class declaring the field.
Class<?> concreteClass = Class.forName("com.javaguides.reflection.fields.User");
Field field = concreteClass.getField("id");
System.out.println(field.getDeclaringClass().getCanonicalName());
Output:
com.javaguides.reflection.fields.User

2.4 Get Field Type

getType() method returns the Class object for the declared field type, if a field is a primitive type, it returns the wrapper class object.
Class<?> concreteClass = Class.forName("com.javaguides.reflection.fields.User");
Field field = concreteClass.getField("id");
System.out.println(field.getType().getCanonicalName());
Output:
int

2.5 Get/Set Public Field Value

We can get and set the value of a field in an Object using reflection.
Class<?> concreteClass = Class.forName("com.javaguides.reflection.fields.User");
User user = new User(10);
Field field = concreteClass.getField("id");

// Get value from concreteClass2 object
System.out.println(field.getInt(user));

// Set value to concreteClass2
field.set(user, 20);

// Get value from concreteClass2 object
System.out.println(field.getInt(user));
Output:
10
20

2.6 Get/Set Private Field Value

We know that private fields and methods can’t be accessible outside of the class but using reflection we can get/set the private field value by turning off the java access check for field modifiers.
Field privateField = Class.forName("com.javaguides.reflection.fields.User").getDeclaredField("name");
//turning off access check with below method call
privateField.setAccessible(true);
User user = new User(10);
System.out.println(privateField.get(user)); 
privateField.set(user, "private string updated");
System.out.println(privateField.get(user));
Output:
null
private string updated

3. Complete Source Code for Reference

package com.javaguides.reflection.fields;

import java.lang.reflect.Field;

/**
 * Reflection For Field class API.
 * @author javaguide.net
 *
 */
public class ReflectionForFields {
  /**
  * Returns a Field object that reflects the specified public member 
  * field of the class or interface represented by this Class object.
  * @throws ClassNotFoundException
  * @throws SecurityException 
  * @throws NoSuchFieldException 
  */
 public static void pulicFields() throws ClassNotFoundException,
     NoSuchFieldException,SecurityException {
     Class<?> concreteClass = Class.forName("com.javaguides.reflection.fields.User");
     Field field = concreteClass.getField("id");
     System.out.println(field.getName());
 }

 /**
  * field object to get the class declaring the field id.
  * @throws ClassNotFoundException
  * @throws NoSuchFieldException
  * @throws SecurityException
  */
 public static void fieldDeclaringClass() throws ClassNotFoundException,
     NoSuchFieldException, SecurityException{
     Class<?> concreteClass = Class.forName("com.javaguides.reflection.fields.User");
     Field field = concreteClass.getField("id");
     System.out.println(field.getDeclaringClass().getCanonicalName());
 }
 
 /**
  * getType() method returns the Class object for the declared field type, 
  * if field is primitive type, it returns the wrapper class object.
  * @throws ClassNotFoundException
  * @throws NoSuchFieldException
  * @throws SecurityException
  */
 public static void fieldType() throws ClassNotFoundException,
     NoSuchFieldException, SecurityException{
     Class<?> concreteClass = Class.forName("com.javaguides.reflection.fields.User");
     Field field = concreteClass.getField("id");
     System.out.println(field.getType().getCanonicalName());
 }
 
 /**
  * get and set public field id value.
  * @throws ClassNotFoundException
  * @throws NoSuchFieldException
  * @throws SecurityException
  * @throws IllegalAccessException 
  * @throws IllegalArgumentException 
  */
 public static void setFieldValue() throws ClassNotFoundException, NoSuchFieldException,
     SecurityException, IllegalArgumentException, IllegalAccessException{
     Class<?> concreteClass = Class.forName("com.javaguides.reflection.fields.User");
     User user = new User(10);
     Field field = concreteClass.getField("id");
  
     // Get value from concreteClass2 object
     System.out.println(field.getInt(user));
  
     // Set value to concreteClass2
     field.set(user, 20);
  
     // Get value from concreteClass2 object
     System.out.println(field.getInt(user));
 }
 
 /**
  * get/set the private field value by turning off the java access check for field modifiers.
  * @throws ClassNotFoundException
  * @throws NoSuchFieldException
  * @throws SecurityException
  * @throws IllegalAccessException 
  * @throws IllegalArgumentException 
  */
 public static void setPrivateFieldValue() throws ClassNotFoundException, 
     NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
     Field privateField = Class.forName("com.javaguides.reflection.fields.User").getDeclaredField("name");
     //turning off access check with below method call
     privateField.setAccessible(true);
     User user = new User(10);
     System.out.println(privateField.get(user)); // prints "private string"
     privateField.set(user, "private string updated");
     System.out.println(privateField.get(user)); //prints "private string updated"
 }
 
 public static void main(String[] args) throws ClassNotFoundException,
     NoSuchFieldException,SecurityException, IllegalArgumentException, IllegalAccessException {
     //pulicFields();
     //fieldDeclaringClass();
     //fieldType();
     //setFieldValue();
     setPrivateFieldValue();
 }
}

4. Reference

Comments