- Java — Different ways to Set Nested Field Value By Reflection
- Examples
- Example POJOs
- Using java.lang.reflect.Field
- Invoking setter via java.lang.reflect.Method
- Using BeanInfo
- Using Apache Commons BeanUtils
- pom.xml
- Using Spring beans
- pom.xml
- Direct Field Access
- Setter Access
- Example Project
- Java — Different ways to Set Field Value by Reflection
- Examples
- Example POJO
- Using java.lang.reflect.Field
- Invoking setter via java.lang.reflect.Method
- Using BeanInfo
- Using Commons BeanUtils
- pom.xml
- Using Spring beans
- pom.xml
- Direct field Access
- Setter access
- Example Project
- Get and Set Field Value using Reflection in Java
- Example
- Output
- References
- Java Reflection — Fields
- Obtaining Field Objects
- Field Name
- Field Type
- Getting and Setting Field Values
Java — Different ways to Set Nested Field Value By Reflection
This tutorial shows different ways to set nest field values by using Java Reflection.
Examples
Example POJOs
package com.logicbig.example; public class Person
package com.logicbig.example; public class Address
package com.logicbig.example; public class AddressLine
package com.logicbig.example; public class City
Using java.lang.reflect.Field
package com.logicbig.example; import java.lang.reflect.Field; public class JavaFieldExample < public static void main(String[] args) throws Exception < Person p = new Person(); Address address = new Address(); address.setLine1(new AddressLine()); address.setCity(new City()); p.setAddress(address); //commenting this will also work System.out.println("before: " + p); setField(p, "address.line1.houseNumber", "4508"); setField(p, "address.line1.street", "Westfall Dr"); setField(p, "address.city.cityName", "Los Alamos"); System.out.println("after: " + p); >private static void setField(Object object, String fieldName, Object fieldValue) throws Exception < if (fieldName.contains(".")) < int firstDotLocation = fieldName.indexOf('.'); String childFieldName = fieldName.substring(0, firstDotLocation); Field field = object.getClass().getDeclaredField(childFieldName); field.setAccessible(true); Object childFieldInstance = field.get(object); if (childFieldInstance == null) < Classtype = field.getType(); //invoking no argument constructor childFieldInstance = type.getConstructor().newInstance(); field.set(object, childFieldInstance); > field.setAccessible(false); setField(childFieldInstance, fieldName.substring(firstDotLocation + 1), fieldValue); > else < Field field = object.getClass().getDeclaredField(fieldName); field.setAccessible(true); field.set(object, fieldValue); field.setAccessible(false); >> >
before: Person, city=City>>
after: Person, city=City>>
Invoking setter via java.lang.reflect.Method
package com.logicbig.example; import java.lang.reflect.Method; public class JavaSetterMethodExample < public static void main(String[] args) throws Exception < Person p = new Person();//must have getters/setters Address address = new Address(); address.setLine1(new AddressLine()); address.setCity(new City()); p.setAddress(address); //commenting this will also work System.out.println("before: " + p); setFieldValue(p, "address.line1.houseNumber", "4508"); setFieldValue(p, "address.line1.street", "Westfall Dr"); setFieldValue(p, "address.city.cityName", "Los Alamos"); System.out.println("after: " + p); >private static void setFieldValue(Object object, String fieldName, Object fieldValue) throws Exception < if (fieldName.contains(".")) < int firstDotLocation = fieldName.indexOf('.'); String childFieldName = fieldName.substring(0, firstDotLocation); Method getter = object.getClass().getDeclaredMethod(fieldToGetterName(childFieldName)); Object childFieldInstance = getter.invoke(object); if (childFieldInstance == null) < Classtype = getter.getReturnType(); //invoking no argument constructor childFieldInstance = type.getConstructor().newInstance(); Method setter = object.getClass().getDeclaredMethod( fieldToSetterName(childFieldName), type); setter.invoke(object, childFieldInstance); > setFieldValue(childFieldInstance, fieldName.substring(firstDotLocation + 1), fieldValue); > else < Method setter = object.getClass().getDeclaredMethod(fieldToSetterName(fieldName), fieldValue.getClass()); setter.invoke(object, fieldValue); >> private static String fieldToGetterName(String fieldName) < return "get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1); >private static String fieldToSetterName(String fieldName) < return "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1); >>
before: Person, city=City>>
after: Person, city=City>>
Using BeanInfo
package com.logicbig.example; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.util.Arrays; public class JavaBeanInfoExample < public static void main(String[] args) throws Exception < Person p = new Person();//must have getters/setters Address address = new Address(); address.setLine1(new AddressLine()); address.setCity(new City()); p.setAddress(address); //commenting this will also work System.out.println("before: " + p); setFieldValue(p, "address.line1.houseNumber", "4508"); setFieldValue(p, "address.line1.street", "Westfall Dr"); setFieldValue(p, "address.city.cityName", "Los Alamos"); System.out.println("after: " + p); >private static void setFieldValue(Object object, String fieldName, Object fieldValue) throws Exception < if (fieldName.contains(".")) < int firstDotLocation = fieldName.indexOf('.'); String childFieldName = fieldName.substring(0, firstDotLocation); PropertyDescriptor pd = findPropertyDescriptor(object.getClass(), childFieldName); Object childFieldInstance = pd.getReadMethod().invoke(object); if (childFieldInstance == null) < Classtype = pd.getPropertyType(); childFieldInstance = type.getConstructor().newInstance(); pd.getWriteMethod().invoke(object, childFieldInstance); > setFieldValue(childFieldInstance, fieldName.substring(firstDotLocation + 1), fieldValue); > else < PropertyDescriptor pd = findPropertyDescriptor(object.getClass(), fieldName); pd.getWriteMethod().invoke(object, fieldValue); >> private static PropertyDescriptor findPropertyDescriptor(Class c, String fieldName) throws Exception < BeanInfo beanInfo = Introspector.getBeanInfo(c); return Arrays.stream(beanInfo.getPropertyDescriptors()) .filter(pd ->pd.getName().equals(fieldName)) .findAny() .orElseThrow(() -> new IllegalArgumentException("field not found: " + fieldName)); > >
before: Person, city=City>>
after: Person, city=City>>
Using Apache Commons BeanUtils
pom.xml
commons-beanutils commons-beanutils 1.9.4
package com.logicbig.example; import org.apache.commons.beanutils.BeanUtils; public class ApacheCommonBeanUtilsExample < public static void main(String[] args) throws Exception < Person p = new Person();//must have getters and setters Address address = new Address(); address.setLine1(new AddressLine()); address.setCity(new City()); p.setAddress(address); System.out.println("before: " + p); BeanUtils.setProperty(p, "address.line1.houseNumber", "4508"); BeanUtils.setProperty(p, "address.line1.street", "Westfall Dr"); BeanUtils.setProperty(p, "address.city.cityName", "Los Alamos"); System.out.println("after: " + p); >>
before: Person, city=City>>
after: Person, city=City>>
Using Spring beans
pom.xml
org.springframework spring-beans 5.2.5.RELEASE
Direct Field Access
package com.logicbig.example; import org.apache.commons.beanutils.BeanUtils; import org.springframework.beans.ConfigurablePropertyAccessor; import org.springframework.beans.PropertyAccessorFactory; public class SpringFieldAccessorExample < public static void main(String[] args) < Person p = new Person(); Address address = new Address(); address.setLine1(new AddressLine()); address.setCity(new City()); p.setAddress(address); System.out.println("before: " + p); ConfigurablePropertyAccessor propertyAccessor = PropertyAccessorFactory.forDirectFieldAccess(p); propertyAccessor.setPropertyValue("address.line1.houseNumber", "4508"); propertyAccessor.setPropertyValue("address.line1.street", "Westfall Dr"); propertyAccessor.setPropertyValue("address.city.cityName", "Los Alamos"); System.out.println("after: " + p); >>
before: Person, city=City>>
after: Person, city=City>>
Setter Access
package com.logicbig.example; import org.springframework.beans.ConfigurablePropertyAccessor; import org.springframework.beans.PropertyAccessorFactory; public class SpringPropertyAccessorExample < public static void main(String[] args) < Person p = new Person();//must have getters/setters Address address = new Address(); address.setLine1(new AddressLine()); address.setCity(new City()); p.setAddress(address); System.out.println("before: " + p); ConfigurablePropertyAccessor propertyAccessor = PropertyAccessorFactory.forBeanPropertyAccess(p); propertyAccessor.setPropertyValue("address.line1.houseNumber", "4508"); propertyAccessor.setPropertyValue("address.line1.street", "Westfall Dr"); propertyAccessor.setPropertyValue("address.city.cityName", "Los Alamos"); System.out.println("after: " + p); >>
before: Person, city=City>>
after: Person, city=City>>
Example Project
Dependencies and Technologies Used:
- commons-beanutils 1.9.4: Apache Commons BeanUtils provides an easy-to-use but flexible wrapper around reflection and introspection.
- spring-beans 5.2.5.RELEASE: Spring Beans.
- JDK 8
- Maven 3.5.4
Java — Different ways to Set Field Value by Reflection
This tutorial shows different ways to set field values by using Java Reflection.
Examples
Example POJO
public class Person < private String name; public String getName() < return name; >public void setName(String name) < this.name = name; >@Override public String toString() < return "Person'; > >
Using java.lang.reflect.Field
package com.logicbig.example; import java.lang.reflect.Field; public class JavaFieldExample < public static void main(String[] args) throws Exception < Person p = new Person(); System.out.println("before: "+p); Field field = Person.class.getDeclaredField("name"); field.setAccessible(true); field.set(p, "Tina"); field.setAccessible(false); System.out.println("after: "+p); >>
before: Person
after: Person
Invoking setter via java.lang.reflect.Method
package com.logicbig.example; import java.lang.reflect.Method; public class JavaSetterMethodExample < public static void main(String[] args) throws Exception < Person p = new Person();//must have setter System.out.println("before: "+p); Method setter = Person.class.getDeclaredMethod("setName", String.class); setter.invoke(p, "Tina"); System.out.println("after: "+p); >>
before: Person
after: Person
Using BeanInfo
package com.logicbig.example; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.util.Arrays; import java.util.Optional; public class JavaBeanInfoExample < public static void main(String[] args) throws Exception < Person p = new Person();//must have getters and setters System.out.println("before: " + p); BeanInfo beanInfo = Introspector.getBeanInfo(Person.class); OptionalpropertyDescriptor = Arrays.stream(beanInfo.getPropertyDescriptors()) .filter(pd -> pd.getName().equals("name")) .findAny(); if (propertyDescriptor.isPresent()) < propertyDescriptor.get().getWriteMethod().invoke(p, "Tina"); System.out.println("after: " + p); >> >
before: Person
after: Person
Using Commons BeanUtils
pom.xml
commons-beanutils commons-beanutils 1.9.4
package com.logicbig.example; import org.apache.commons.beanutils.BeanUtils; public class ApacheCommonBeanUtilsExample < public static void main(String[] args) throws Exception < Person p = new Person();//must have getters and setters System.out.println("before: " + p); BeanUtils.setProperty(p, "name", "Tina"); System.out.println("after: " + p); >>
before: Person
after: Person
Using Spring beans
pom.xml
org.springframework spring-beans 5.2.5.RELEASE
Direct field Access
package com.logicbig.example; import org.springframework.beans.ConfigurablePropertyAccessor; import org.springframework.beans.PropertyAccessorFactory; public class SpringFieldAccessorExample < public static void main(String[] args) < Person p = new Person(); System.out.println("before: "+p); ConfigurablePropertyAccessor propertyAccessor = PropertyAccessorFactory.forDirectFieldAccess(p); propertyAccessor.setPropertyValue("name", "Tina"); System.out.println("after: "+p); >>
before: Person
after: Person
Setter access
package com.logicbig.example; import org.springframework.beans.ConfigurablePropertyAccessor; import org.springframework.beans.PropertyAccessorFactory; public class SpringPropertyAccessorExample < public static void main(String[] args) < Person p = new Person();//must have getters and setters System.out.println("before: " + p); ConfigurablePropertyAccessor propertyAccessor = PropertyAccessorFactory.forBeanPropertyAccess(p); propertyAccessor.setPropertyValue("name", "Tina"); System.out.println("after: " + p); >>
before: Person
after: Person
Example Project
Dependencies and Technologies Used:
- commons-beanutils 1.9.4: Apache Commons BeanUtils provides an easy-to-use but flexible wrapper around reflection and introspection.
- spring-beans 5.2.5.RELEASE: Spring Beans.
- JDK 8
- Maven 3.5.4
Get and Set Field Value using Reflection in Java
Java Reflection provides classes and interfaces for obtaining reflective information about classes and objects. Reflection allows programmatic access to information about the fields, methods and constructors of loaded classes, and the use of reflected fields, methods, and constructors to operate on their underlying counterparts, within security restrictions. Also provides the possibility to instantiate new objects, invoke methods and get/set field values.
Here is an example how to get and set field values.
Example
For testing will create a simple class with 3 fields: first public, second private and third protected.
package com.admfactory.reflect; public class Username < public int id; private String name; protected String email; public Username() < >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; >public String getEmail() < return email; >public void setEmail(String email) < this.email = email; >public void display() < System.out.println(String.format("Username: [id:%d, name:%s, email:%s]", id, name, email)); >>
Here is an example how to set and get the fields using reflection.
package com.admfactory.reflect; import java.lang.reflect.Field; public class FieldTest < public static void main(String[] args) throws Exception < System.out.println("get and set fild values using reflection example"); Username user = new Username(); System.out.println(); Classclazz = Username.class; Field fieldID = clazz.getField("id"); fieldID.set(user, 100); System.out.println("Id value set using reflection: " + user.id); int value get using reflection: " + id); System.out.println(); Field fieldNAME = clazz.getDeclaredField("name"); fieldNAME.setAccessible(true); fieldNAME.set(user, "Admin"); System.out.println("Name value set using reflection: " + user.getName()); String name = (String) fieldNAME.get(user); System.out.println("Name value get using reflection: " + name); Field fieldEMAIL = clazz.getDeclaredField("email"); fieldEMAIL.setAccessible(true); fieldEMAIL.set(user, "admin@example.com"); System.out.println("Email value set using reflection: " + user.getEmail()); String email = (String) fieldEMAIL.get(user); System.out.println("Email value get using reflection: " + email); System.out.println(); user.display(); > >
If you want to get the public field you can use getField method, for private or protected fields you need to use getDeclaredField method. As a best practice you can always use getDeclaredField method. Also for private and protected fields you need to set the field as accessible, otherwise an java.lang.IllegalAccessException exception will be thrown.
Output
get and set fild values using reflection example Id value set using reflection: 100 Id value get using reflection: 100 Name value set using reflection: Admin Name value get using reflection: Admin Email value set using reflection: admin@example.com Email value get using reflection: admin@example.com Username: [id:100, name:Admin, email:admin@example.com]
References
Java Reflection — Fields
Using Java Reflection you can inspect the fields (member variables) of classes and get / set them at runtime. This is done via the Java class java.lang.reflect.Field . This text will get into more detail about the Java Field object. Remember to check the JavaDoc from Sun out too.
Obtaining Field Objects
The Field class is obtained from the Class object. Here is an example:
Class aClass = . //obtain class object Field[] fields = aClass.getFields();
The Field[] array will have one Field instance for each public field declared in the class.
If you know the name of the field you want to access, you can access it like this:
Class aClass = MyObject.class Field field = aClass.getField("someField");
The example above will return the Field instance corresponding to the field someField as declared in the MyObject below:
If no field exists with the name given as parameter to the getField() method, a NoSuchFieldException is thrown.
Field Name
Once you have obtained a Field instance, you can get its field name using the Field.getName() method, like this:
Field field = . //obtain field object String fieldName = field.getName();
Field Type
You can determine the field type (String, int etc.) of a field using the Field.getType() method:
Field field = aClass.getField("someField"); Object fieldType = field.getType();
Getting and Setting Field Values
Once you have obtained a Field reference you can get and set its values using the Field.get() and Field.set() methods, like this:
Class aClass = MyObject.class Field field = aClass.getField("someField"); MyObject objectInstance = new MyObject(); Object value = field.get(objectInstance); field.set(objetInstance, value);
The objectInstance parameter passed to the get and set method should be an instance of the class that owns the field. In the above example an instance of MyObject is used, because the someField is an instance member of the MyObject class.
It the field is a static field (public static . ) pass null as parameter to the get and set methods, instead of the objectInstance parameter passed above.