/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.lang.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Iterator;

import org.apache.commons.lang.ClassUtils;

Utilities for working with fields by reflection. Adapted and refactored from the dormant [reflect] Commons sandbox component.

The ability is provided to break the scoping restrictions coded by the programmer. This can allow fields to be changed that shouldn't be. This facility should be used with care.

Author:Apache Software Foundation, Matt Benson
Since:2.5
Version:$Id: FieldUtils.java 1057009 2011-01-09 19:48:06Z niallp $
/** * Utilities for working with fields by reflection. Adapted and refactored * from the dormant [reflect] Commons sandbox component. * <p> * The ability is provided to break the scoping restrictions coded by the * programmer. This can allow fields to be changed that shouldn't be. This * facility should be used with care. * * @author Apache Software Foundation * @author Matt Benson * @since 2.5 * @version $Id: FieldUtils.java 1057009 2011-01-09 19:48:06Z niallp $ */
public class FieldUtils {
FieldUtils instances should NOT be constructed in standard programming.

This constructor is public to permit tools that require a JavaBean instance to operate.

/** * FieldUtils instances should NOT be constructed in standard programming. * <p> * This constructor is public to permit tools that require a JavaBean instance * to operate. */
public FieldUtils() { super(); }
Gets an accessible Field by name respecting scope. Superclasses/interfaces will be considered.
Params:
  • cls – the class to reflect, must not be null
  • fieldName – the field name to obtain
Throws:
Returns:the Field object
/** * Gets an accessible <code>Field</code> by name respecting scope. * Superclasses/interfaces will be considered. * * @param cls the class to reflect, must not be null * @param fieldName the field name to obtain * @return the Field object * @throws IllegalArgumentException if the class or field name is null */
public static Field getField(Class cls, String fieldName) { Field field = getField(cls, fieldName, false); MemberUtils.setAccessibleWorkaround(field); return field; }
Gets an accessible Field by name breaking scope if requested. Superclasses/interfaces will be considered.
Params:
  • cls – the class to reflect, must not be null
  • fieldName – the field name to obtain
  • forceAccess – whether to break scope restrictions using the setAccessible method. False will only match public fields.
Throws:
Returns:the Field object
/** * Gets an accessible <code>Field</code> by name breaking scope * if requested. Superclasses/interfaces will be considered. * * @param cls the class to reflect, must not be null * @param fieldName the field name to obtain * @param forceAccess whether to break scope restrictions using the * <code>setAccessible</code> method. <code>False</code> will only * match public fields. * @return the Field object * @throws IllegalArgumentException if the class or field name is null */
public static Field getField(final Class cls, String fieldName, boolean forceAccess) { if (cls == null) { throw new IllegalArgumentException("The class must not be null"); } if (fieldName == null) { throw new IllegalArgumentException("The field name must not be null"); } // Sun Java 1.3 has a bugged implementation of getField hence we write the // code ourselves // getField() will return the Field object with the declaring class // set correctly to the class that declares the field. Thus requesting the // field on a subclass will return the field from the superclass. // // priority order for lookup: // searchclass private/protected/package/public // superclass protected/package/public // private/different package blocks access to further superclasses // implementedinterface public // check up the superclass hierarchy for (Class acls = cls; acls != null; acls = acls.getSuperclass()) { try { Field field = acls.getDeclaredField(fieldName); // getDeclaredField checks for non-public scopes as well // and it returns accurate results if (!Modifier.isPublic(field.getModifiers())) { if (forceAccess) { field.setAccessible(true); } else { continue; } } return field; } catch (NoSuchFieldException ex) { // ignore } } // check the public interface case. This must be manually searched for // incase there is a public supersuperclass field hidden by a private/package // superclass field. Field match = null; for (Iterator intf = ClassUtils.getAllInterfaces(cls).iterator(); intf .hasNext();) { try { Field test = ((Class) intf.next()).getField(fieldName); if (match != null) { throw new IllegalArgumentException( "Reference to field " + fieldName + " is ambiguous relative to " + cls + "; a matching field exists on two or more implemented interfaces."); } match = test; } catch (NoSuchFieldException ex) { // ignore } } return match; }
Gets an accessible Field by name respecting scope. Only the specified class will be considered.
Params:
  • cls – the class to reflect, must not be null
  • fieldName – the field name to obtain
Throws:
Returns:the Field object
/** * Gets an accessible <code>Field</code> by name respecting scope. * Only the specified class will be considered. * * @param cls the class to reflect, must not be null * @param fieldName the field name to obtain * @return the Field object * @throws IllegalArgumentException if the class or field name is null */
public static Field getDeclaredField(Class cls, String fieldName) { return getDeclaredField(cls, fieldName, false); }
Gets an accessible Field by name breaking scope if requested. Only the specified class will be considered.
Params:
  • cls – the class to reflect, must not be null
  • fieldName – the field name to obtain
  • forceAccess – whether to break scope restrictions using the setAccessible method. False will only match public fields.
Throws:
Returns:the Field object
/** * Gets an accessible <code>Field</code> by name breaking scope * if requested. Only the specified class will be considered. * * @param cls the class to reflect, must not be null * @param fieldName the field name to obtain * @param forceAccess whether to break scope restrictions using the * <code>setAccessible</code> method. False will only match public fields. * @return the Field object * @throws IllegalArgumentException if the class or field name is null */
public static Field getDeclaredField(Class cls, String fieldName, boolean forceAccess) { if (cls == null) { throw new IllegalArgumentException("The class must not be null"); } if (fieldName == null) { throw new IllegalArgumentException("The field name must not be null"); } try { // only consider the specified class by using getDeclaredField() Field field = cls.getDeclaredField(fieldName); if (!MemberUtils.isAccessible(field)) { if (forceAccess) { field.setAccessible(true); } else { return null; } } return field; } catch (NoSuchFieldException e) { } return null; }
Read an accessible static Field.
Params:
  • field – to read
Throws:
Returns:the field value
/** * Read an accessible static Field. * @param field to read * @return the field value * @throws IllegalArgumentException if the field is null or not static * @throws IllegalAccessException if the field is not accessible */
public static Object readStaticField(Field field) throws IllegalAccessException { return readStaticField(field, false); }
Read a static Field.
Params:
  • field – to read
  • forceAccess – whether to break scope restrictions using the setAccessible method.
Throws:
Returns:the field value
/** * Read a static Field. * @param field to read * @param forceAccess whether to break scope restrictions using the * <code>setAccessible</code> method. * @return the field value * @throws IllegalArgumentException if the field is null or not static * @throws IllegalAccessException if the field is not made accessible */
public static Object readStaticField(Field field, boolean forceAccess) throws IllegalAccessException { if (field == null) { throw new IllegalArgumentException("The field must not be null"); } if (!Modifier.isStatic(field.getModifiers())) { throw new IllegalArgumentException("The field '" + field.getName() + "' is not static"); } return readField(field, (Object) null, forceAccess); }
Read the named public static field. Superclasses will be considered.
Params:
  • cls – the class to reflect, must not be null
  • fieldName – the field name to obtain
Throws:
Returns:the value of the field
/** * Read the named public static field. Superclasses will be considered. * @param cls the class to reflect, must not be null * @param fieldName the field name to obtain * @return the value of the field * @throws IllegalArgumentException if the class or field name is null * @throws IllegalAccessException if the field is not accessible */
public static Object readStaticField(Class cls, String fieldName) throws IllegalAccessException { return readStaticField(cls, fieldName, false); }
Read the named static field. Superclasses will be considered.
Params:
  • cls – the class to reflect, must not be null
  • fieldName – the field name to obtain
  • forceAccess – whether to break scope restrictions using the setAccessible method. False will only match public fields.
Throws:
Returns:the Field object
/** * Read the named static field. Superclasses will be considered. * @param cls the class to reflect, must not be null * @param fieldName the field name to obtain * @param forceAccess whether to break scope restrictions using the * <code>setAccessible</code> method. <code>False</code> will only * match public fields. * @return the Field object * @throws IllegalArgumentException if the class or field name is null * @throws IllegalAccessException if the field is not made accessible */
public static Object readStaticField(Class cls, String fieldName, boolean forceAccess) throws IllegalAccessException { Field field = getField(cls, fieldName, forceAccess); if (field == null) { throw new IllegalArgumentException("Cannot locate field " + fieldName + " on " + cls); } //already forced access above, don't repeat it here: return readStaticField(field, false); }
Gets a static Field value by name. The field must be public. Only the specified class will be considered.
Params:
  • cls – the class to reflect, must not be null
  • fieldName – the field name to obtain
Throws:
Returns:the value of the field
/** * Gets a static Field value by name. The field must be public. * Only the specified class will be considered. * * @param cls the class to reflect, must not be null * @param fieldName the field name to obtain * @return the value of the field * @throws IllegalArgumentException if the class or field name is null * @throws IllegalAccessException if the field is not accessible */
public static Object readDeclaredStaticField(Class cls, String fieldName) throws IllegalAccessException { return readDeclaredStaticField(cls, fieldName, false); }
Gets a static Field value by name. Only the specified class will be considered.
Params:
  • cls – the class to reflect, must not be null
  • fieldName – the field name to obtain
  • forceAccess – whether to break scope restrictions using the setAccessible method. False will only match public fields.
Throws:
Returns:the Field object
/** * Gets a static Field value by name. Only the specified class will * be considered. * * @param cls the class to reflect, must not be null * @param fieldName the field name to obtain * @param forceAccess whether to break scope restrictions using the * <code>setAccessible</code> method. <code>False</code> will only * match public fields. * @return the Field object * @throws IllegalArgumentException if the class or field name is null * @throws IllegalAccessException if the field is not made accessible */
public static Object readDeclaredStaticField(Class cls, String fieldName, boolean forceAccess) throws IllegalAccessException { Field field = getDeclaredField(cls, fieldName, forceAccess); if (field == null) { throw new IllegalArgumentException("Cannot locate declared field " + cls.getName() + "." + fieldName); } //already forced access above, don't repeat it here: return readStaticField(field, false); }
Read an accessible Field.
Params:
  • field – the field to use
  • target – the object to call on, may be null for static fields
Throws:
Returns:the field value
/** * Read an accessible Field. * @param field the field to use * @param target the object to call on, may be null for static fields * @return the field value * @throws IllegalArgumentException if the field is null * @throws IllegalAccessException if the field is not accessible */
public static Object readField(Field field, Object target) throws IllegalAccessException { return readField(field, target, false); }
Read a Field.
Params:
  • field – the field to use
  • target – the object to call on, may be null for static fields
  • forceAccess – whether to break scope restrictions using the setAccessible method.
Throws:
Returns:the field value
/** * Read a Field. * @param field the field to use * @param target the object to call on, may be null for static fields * @param forceAccess whether to break scope restrictions using the * <code>setAccessible</code> method. * @return the field value * @throws IllegalArgumentException if the field is null * @throws IllegalAccessException if the field is not made accessible */
public static Object readField(Field field, Object target, boolean forceAccess) throws IllegalAccessException { if (field == null) { throw new IllegalArgumentException("The field must not be null"); } if (forceAccess && !field.isAccessible()) { field.setAccessible(true); } else { MemberUtils.setAccessibleWorkaround(field); } return field.get(target); }
Read the named public field. Superclasses will be considered.
Params:
  • target – the object to reflect, must not be null
  • fieldName – the field name to obtain
Throws:
Returns:the value of the field
/** * Read the named public field. Superclasses will be considered. * @param target the object to reflect, must not be null * @param fieldName the field name to obtain * @return the value of the field * @throws IllegalArgumentException if the class or field name is null * @throws IllegalAccessException if the named field is not public */
public static Object readField(Object target, String fieldName) throws IllegalAccessException { return readField(target, fieldName, false); }
Read the named field. Superclasses will be considered.
Params:
  • target – the object to reflect, must not be null
  • fieldName – the field name to obtain
  • forceAccess – whether to break scope restrictions using the setAccessible method. False will only match public fields.
Throws:
Returns:the field value
/** * Read the named field. Superclasses will be considered. * @param target the object to reflect, must not be null * @param fieldName the field name to obtain * @param forceAccess whether to break scope restrictions using the * <code>setAccessible</code> method. <code>False</code> will only * match public fields. * @return the field value * @throws IllegalArgumentException if the class or field name is null * @throws IllegalAccessException if the named field is not made accessible */
public static Object readField(Object target, String fieldName, boolean forceAccess) throws IllegalAccessException { if (target == null) { throw new IllegalArgumentException("target object must not be null"); } Class cls = target.getClass(); Field field = getField(cls, fieldName, forceAccess); if (field == null) { throw new IllegalArgumentException("Cannot locate field " + fieldName + " on " + cls); } //already forced access above, don't repeat it here: return readField(field, target); }
Read the named public field. Only the class of the specified object will be considered.
Params:
  • target – the object to reflect, must not be null
  • fieldName – the field name to obtain
Throws:
Returns:the value of the field
/** * Read the named public field. Only the class of the specified object will be considered. * @param target the object to reflect, must not be null * @param fieldName the field name to obtain * @return the value of the field * @throws IllegalArgumentException if the class or field name is null * @throws IllegalAccessException if the named field is not public */
public static Object readDeclaredField(Object target, String fieldName) throws IllegalAccessException { return readDeclaredField(target, fieldName, false); }

<>Gets a Field value by name. Only the class of the specified object will be considered.

Params:
  • target – the object to reflect, must not be null
  • fieldName – the field name to obtain
  • forceAccess – whether to break scope restrictions using the setAccessible method. False will only match public fields.
Throws:
Returns:the Field object
/** * <p<>Gets a Field value by name. Only the class of the specified * object will be considered. * * @param target the object to reflect, must not be null * @param fieldName the field name to obtain * @param forceAccess whether to break scope restrictions using the * <code>setAccessible</code> method. <code>False</code> will only * match public fields. * @return the Field object * @throws IllegalArgumentException if <code>target</code> or <code>fieldName</code> is null * @throws IllegalAccessException if the field is not made accessible */
public static Object readDeclaredField(Object target, String fieldName, boolean forceAccess) throws IllegalAccessException { if (target == null) { throw new IllegalArgumentException("target object must not be null"); } Class cls = target.getClass(); Field field = getDeclaredField(cls, fieldName, forceAccess); if (field == null) { throw new IllegalArgumentException("Cannot locate declared field " + cls.getName() + "." + fieldName); } //already forced access above, don't repeat it here: return readField(field, target); }
Write a public static Field.
Params:
  • field – to write
  • value – to set
Throws:
/** * Write a public static Field. * @param field to write * @param value to set * @throws IllegalArgumentException if the field is null or not static * @throws IllegalAccessException if the field is not public or is final */
public static void writeStaticField(Field field, Object value) throws IllegalAccessException { writeStaticField(field, value, false); }
Write a static Field.
Params:
  • field – to write
  • value – to set
  • forceAccess – whether to break scope restrictions using the setAccessible method. False will only match public fields.
Throws:
/** * Write a static Field. * @param field to write * @param value to set * @param forceAccess whether to break scope restrictions using the * <code>setAccessible</code> method. <code>False</code> will only * match public fields. * @throws IllegalArgumentException if the field is null or not static * @throws IllegalAccessException if the field is not made accessible or is final */
public static void writeStaticField(Field field, Object value, boolean forceAccess) throws IllegalAccessException { if (field == null) { throw new IllegalArgumentException("The field must not be null"); } if (!Modifier.isStatic(field.getModifiers())) { throw new IllegalArgumentException("The field '" + field.getName() + "' is not static"); } writeField(field, (Object) null, value, forceAccess); }
Write a named public static Field. Superclasses will be considered.
Params:
  • cls – Class on which the Field is to be found
  • fieldName – to write
  • value – to set
Throws:
/** * Write a named public static Field. Superclasses will be considered. * @param cls Class on which the Field is to be found * @param fieldName to write * @param value to set * @throws IllegalArgumentException if the field cannot be located or is not static * @throws IllegalAccessException if the field is not public or is final */
public static void writeStaticField(Class cls, String fieldName, Object value) throws IllegalAccessException { writeStaticField(cls, fieldName, value, false); }
Write a named static Field. Superclasses will be considered.
Params:
  • cls – Class on which the Field is to be found
  • fieldName – to write
  • value – to set
  • forceAccess – whether to break scope restrictions using the setAccessible method. False will only match public fields.
Throws:
/** * Write a named static Field. Superclasses will be considered. * @param cls Class on which the Field is to be found * @param fieldName to write * @param value to set * @param forceAccess whether to break scope restrictions using the * <code>setAccessible</code> method. <code>False</code> will only * match public fields. * @throws IllegalArgumentException if the field cannot be located or is not static * @throws IllegalAccessException if the field is not made accessible or is final */
public static void writeStaticField(Class cls, String fieldName, Object value, boolean forceAccess) throws IllegalAccessException { Field field = getField(cls, fieldName, forceAccess); if (field == null) { throw new IllegalArgumentException("Cannot locate field " + fieldName + " on " + cls); } //already forced access above, don't repeat it here: writeStaticField(field, value); }
Write a named public static Field. Only the specified class will be considered.
Params:
  • cls – Class on which the Field is to be found
  • fieldName – to write
  • value – to set
Throws:
/** * Write a named public static Field. Only the specified class will be considered. * @param cls Class on which the Field is to be found * @param fieldName to write * @param value to set * @throws IllegalArgumentException if the field cannot be located or is not static * @throws IllegalAccessException if the field is not public or is final */
public static void writeDeclaredStaticField(Class cls, String fieldName, Object value) throws IllegalAccessException { writeDeclaredStaticField(cls, fieldName, value, false); }
Write a named static Field. Only the specified class will be considered.
Params:
  • cls – Class on which the Field is to be found
  • fieldName – to write
  • value – to set
  • forceAccess – whether to break scope restrictions using the setAccessible method. False will only match public fields.
Throws:
/** * Write a named static Field. Only the specified class will be considered. * @param cls Class on which the Field is to be found * @param fieldName to write * @param value to set * @param forceAccess whether to break scope restrictions using the * <code>setAccessible</code> method. <code>False</code> will only * match public fields. * @throws IllegalArgumentException if the field cannot be located or is not static * @throws IllegalAccessException if the field is not made accessible or is final */
public static void writeDeclaredStaticField(Class cls, String fieldName, Object value, boolean forceAccess) throws IllegalAccessException { Field field = getDeclaredField(cls, fieldName, forceAccess); if (field == null) { throw new IllegalArgumentException("Cannot locate declared field " + cls.getName() + "." + fieldName); } //already forced access above, don't repeat it here: writeField(field, (Object) null, value); }
Write an accessible field.
Params:
  • field – to write
  • target – the object to call on, may be null for static fields
  • value – to set
Throws:
/** * Write an accessible field. * @param field to write * @param target the object to call on, may be null for static fields * @param value to set * @throws IllegalArgumentException if the field is null * @throws IllegalAccessException if the field is not accessible or is final */
public static void writeField(Field field, Object target, Object value) throws IllegalAccessException { writeField(field, target, value, false); }
Write a field.
Params:
  • field – to write
  • target – the object to call on, may be null for static fields
  • value – to set
  • forceAccess – whether to break scope restrictions using the setAccessible method. False will only match public fields.
Throws:
/** * Write a field. * @param field to write * @param target the object to call on, may be null for static fields * @param value to set * @param forceAccess whether to break scope restrictions using the * <code>setAccessible</code> method. <code>False</code> will only * match public fields. * @throws IllegalArgumentException if the field is null * @throws IllegalAccessException if the field is not made accessible or is final */
public static void writeField(Field field, Object target, Object value, boolean forceAccess) throws IllegalAccessException { if (field == null) { throw new IllegalArgumentException("The field must not be null"); } if (forceAccess && !field.isAccessible()) { field.setAccessible(true); } else { MemberUtils.setAccessibleWorkaround(field); } field.set(target, value); }
Write a public field. Superclasses will be considered.
Params:
  • target – the object to reflect, must not be null
  • fieldName – the field name to obtain
  • value – to set
Throws:
/** * Write a public field. Superclasses will be considered. * @param target the object to reflect, must not be null * @param fieldName the field name to obtain * @param value to set * @throws IllegalArgumentException if <code>target</code> or <code>fieldName</code> is null * @throws IllegalAccessException if the field is not accessible */
public static void writeField(Object target, String fieldName, Object value) throws IllegalAccessException { writeField(target, fieldName, value, false); }
Write a field. Superclasses will be considered.
Params:
  • target – the object to reflect, must not be null
  • fieldName – the field name to obtain
  • value – to set
  • forceAccess – whether to break scope restrictions using the setAccessible method. False will only match public fields.
Throws:
/** * Write a field. Superclasses will be considered. * @param target the object to reflect, must not be null * @param fieldName the field name to obtain * @param value to set * @param forceAccess whether to break scope restrictions using the * <code>setAccessible</code> method. <code>False</code> will only * match public fields. * @throws IllegalArgumentException if <code>target</code> or <code>fieldName</code> is null * @throws IllegalAccessException if the field is not made accessible */
public static void writeField(Object target, String fieldName, Object value, boolean forceAccess) throws IllegalAccessException { if (target == null) { throw new IllegalArgumentException("target object must not be null"); } Class cls = target.getClass(); Field field = getField(cls, fieldName, forceAccess); if (field == null) { throw new IllegalArgumentException("Cannot locate declared field " + cls.getName() + "." + fieldName); } //already forced access above, don't repeat it here: writeField(field, target, value); }
Write a public field. Only the specified class will be considered.
Params:
  • target – the object to reflect, must not be null
  • fieldName – the field name to obtain
  • value – to set
Throws:
/** * Write a public field. Only the specified class will be considered. * @param target the object to reflect, must not be null * @param fieldName the field name to obtain * @param value to set * @throws IllegalArgumentException if <code>target</code> or <code>fieldName</code> is null * @throws IllegalAccessException if the field is not made accessible */
public static void writeDeclaredField(Object target, String fieldName, Object value) throws IllegalAccessException { writeDeclaredField(target, fieldName, value, false); }
Write a public field. Only the specified class will be considered.
Params:
  • target – the object to reflect, must not be null
  • fieldName – the field name to obtain
  • value – to set
  • forceAccess – whether to break scope restrictions using the setAccessible method. False will only match public fields.
Throws:
/** * Write a public field. Only the specified class will be considered. * @param target the object to reflect, must not be null * @param fieldName the field name to obtain * @param value to set * @param forceAccess whether to break scope restrictions using the * <code>setAccessible</code> method. <code>False</code> will only * match public fields. * @throws IllegalArgumentException if <code>target</code> or <code>fieldName</code> is null * @throws IllegalAccessException if the field is not made accessible */
public static void writeDeclaredField(Object target, String fieldName, Object value, boolean forceAccess) throws IllegalAccessException { if (target == null) { throw new IllegalArgumentException("target object must not be null"); } Class cls = target.getClass(); Field field = getDeclaredField(cls, fieldName, forceAccess); if (field == null) { throw new IllegalArgumentException("Cannot locate declared field " + cls.getName() + "." + fieldName); } //already forced access above, don't repeat it here: writeField(field, target, value); } }