Java
Reflection
Object-Oriented Programming
Property Manipulation
Coding Techniques

Set object property using reflection

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Reflection lets you inspect and modify objects at runtime when compile-time types are not enough. It is useful in frameworks, generic mappers, test tooling, and admin utilities where field names or property names arrive as data. The key is to use reflection in a controlled way so dynamic behavior does not reduce safety and maintainability.

When Reflection Is the Right Tool

Most application code should use normal method calls. Reflection becomes valuable when you need one reusable component that can work with many unrelated classes, such as a CSV importer, configuration binder, or generic patch endpoint. In these cases, hard-coding setter calls for every model becomes expensive and brittle.

Before implementing reflection-based mutation, define clear rules:

  • Which fields are allowed to change.
  • What input types are accepted.
  • How conversion errors are reported.
  • Whether private members are allowed.

These rules prevent dangerous behavior where arbitrary input can mutate sensitive fields.

Field-Based Property Updates in Java

The direct approach uses java.lang.reflect.Field. You find a field by name, make it accessible, convert the incoming value to the correct type, and assign it.

java
1import java.lang.reflect.Field;
2
3public class ReflectionSetterDemo {
4    static class Person {
5        private String name;
6        private int age;
7        private boolean active;
8
9        @Override
10        public String toString() {
11            return "Person{name='" + name + "', age=" + age + ", active=" + active + "}";
12        }
13    }
14
15    public static void main(String[] args) throws Exception {
16        Person p = new Person();
17
18        setFieldValue(p, "name", "Avery");
19        setFieldValue(p, "age", "34");
20        setFieldValue(p, "active", "true");
21
22        System.out.println(p);
23    }
24
25    public static void setFieldValue(Object target, String fieldName, Object rawValue) throws Exception {
26        Field field = findField(target.getClass(), fieldName);
27        if (field == null) {
28            throw new IllegalArgumentException("Unknown field: " + fieldName);
29        }
30
31        field.setAccessible(true);
32        Object converted = convert(rawValue, field.getType());
33        field.set(target, converted);
34    }
35
36    private static Field findField(Class<?> type, String fieldName) {
37        Class<?> current = type;
38        while (current != null) {
39            try {
40                return current.getDeclaredField(fieldName);
41            } catch (NoSuchFieldException ignored) {
42                current = current.getSuperclass();
43            }
44        }
45        return null;
46    }
47
48    private static Object convert(Object value, Class<?> targetType) {
49        if (value == null) return null;
50
51        String text = String.valueOf(value);
52
53        if (targetType == String.class) return text;
54        if (targetType == int.class || targetType == Integer.class) return Integer.parseInt(text);
55        if (targetType == long.class || targetType == Long.class) return Long.parseLong(text);
56        if (targetType == boolean.class || targetType == Boolean.class) return Boolean.parseBoolean(text);
57
58        throw new IllegalArgumentException("Unsupported type: " + targetType.getName());
59    }
60}

This code is runnable and intentionally strict. Unsupported types fail fast, which is usually better than silent coercion.

Setter-Based Updates for Better Encapsulation

Direct field mutation bypasses business rules that may exist inside setters. If your domain classes validate state in setter methods, invoke methods rather than fields. This keeps validation logic active and reduces invalid object states.

java
1import java.lang.reflect.Method;
2
3public class SetterInvoker {
4    public static void setBySetter(Object target, String propertyName, Object rawValue) throws Exception {
5        String setterName = "set" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
6
7        Method chosen = null;
8        for (Method m : target.getClass().getMethods()) {
9            if (m.getName().equals(setterName) && m.getParameterCount() == 1) {
10                chosen = m;
11                break;
12            }
13        }
14
15        if (chosen == null) {
16            throw new IllegalArgumentException("No setter for: " + propertyName);
17        }
18
19        Class<?> paramType = chosen.getParameterTypes()[0];
20        Object converted = ReflectionSetterDemo.convert(rawValue, paramType);
21        chosen.invoke(target, converted);
22    }
23}

A common production pattern is to keep a whitelist of allowed properties, then call setBySetter only for those names.

Performance and Reliability Considerations

Reflection is slower than direct calls, but in many request flows the overhead is acceptable. If profiling shows reflection hot spots, cache field and method lookups in a map keyed by class and property name. Caching removes repeated metadata scanning and often provides most of the needed gain.

Reliability is usually a bigger concern than raw speed. Add strong error messages with property name, target class, and expected type. That makes bad input easy to diagnose.

In frameworks and APIs, wrap reflection errors in application-level exceptions. A generic stack trace from IllegalArgumentException is not enough for clients and support teams.

Common Pitfalls

  • Mutating private fields that should stay controlled. Prefer setters when domain validation exists.
  • Skipping type conversion rules. Always convert deliberately and reject unknown conversions.
  • Allowing any property name from user input. Use a whitelist to prevent unintended updates.
  • Ignoring inherited fields. Search the class hierarchy when field access is required.
  • Repeating reflection lookup in hot loops. Cache metadata when performance matters.

Summary

  • Reflection is powerful for generic mappers and runtime-driven property updates.
  • Field-based mutation is simple but can bypass business validation.
  • Setter-based mutation better preserves encapsulation and invariants.
  • Explicit conversion, clear errors, and property whitelists make reflection safe in production.
  • Cache metadata only after you confirm performance pressure with profiling.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.