LANG-934 - Add removeFinalModifier to FieldUtils

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1546799 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Maurizio Cucchiara 2013-12-01 10:34:02 +00:00
parent 030f0d3d40
commit c288d29601
4 changed files with 42 additions and 4 deletions

View File

@ -22,6 +22,7 @@
<body>
<release version="3.2" date="TBA" description="Next release">
<action issue="LANG-934" type="add" dev="mcucchiara">Add removeFinalModifier to FieldUtils</action>
<action issue="LANG-863" type="add" due-to="Daneel S. Yaitskov" dev="sebb">Method returns number of inheritance hops between parent and subclass</action>
<action issue="LANG-932" type="fix" due-to="Ville Skyttä" dev="sebb">Spelling fixes</action>
<action issue="LANG-931" type="update" dev="britter" due-to="Christoph Schneegans">Misleading Javadoc comment in StrBuilderReader class</action>

View File

@ -16,15 +16,15 @@
*/
package org.apache.commons.lang3.reflect;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
/**
* Utilities for working with {@link Field}s by reflection. Adapted and refactored from the dormant [reflect] Commons sandbox
* component.
@ -665,6 +665,28 @@ public static void writeField(final Field field, final Object target, final Obje
field.set(target, value);
}
/**
* Remove the final modifier from a {@link Field}
* @param field to remove the final modifier
* @throws IllegalArgumentException
* if the field is {@code null}
*/
public static void removeFinalModifier(Field field) {
Validate.isTrue(field != null, "The field must not be null");
try {
if(Modifier.isFinal(field.getModifiers())){
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
}
} catch (NoSuchFieldException ignored) {
// The field class contains always a modifiers field
} catch (IllegalAccessException ignored) {
// The modifiers field is made accessible
}
}
/**
* Writes a {@code public} {@link Field}. Superclasses will be considered.
*

View File

@ -1253,4 +1253,11 @@ public void testAmbig() {
FieldUtils.getField(Ambig.class, "VALUE");
}
@Test
public void testRemoveFinalModifier() throws Exception {
Field field = StaticContainer.class.getDeclaredField("IMMUTABLE_PRIVATE_2");
assertTrue(Modifier.isFinal(field.getModifiers()));
FieldUtils.removeFinalModifier(field);
assertFalse(Modifier.isFinal(field.getModifiers()));
}
}

View File

@ -22,10 +22,18 @@
public class StaticContainer {
public static final Object IMMUTABLE_PUBLIC = "public";
protected static final Object IMMUTABLE_PROTECTED = "protected";
@SuppressWarnings("unused")
static final Object IMMUTABLE_PACKAGE = "";
@SuppressWarnings("unused")
private static final Object IMMUTABLE_PRIVATE = "private";
/**
* This final modifier of this field is meant to be removed by a test.
* Using this field may produce unpredictable results.
*/
@SuppressWarnings("unused")
private static final Object IMMUTABLE_PRIVATE_2 = "private";
public static Object mutablePublic;
protected static Object mutableProtected;
static Object mutablePackage;