diff --git a/hutool-core/src/main/java/cn/hutool/core/reflect/ModifierUtil.java b/hutool-core/src/main/java/cn/hutool/core/reflect/ModifierUtil.java index 9560e564e..694489028 100644 --- a/hutool-core/src/main/java/cn/hutool/core/reflect/ModifierUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/reflect/ModifierUtil.java @@ -1,7 +1,9 @@ package cn.hutool.core.reflect; +import cn.hutool.core.exceptions.UtilException; import cn.hutool.core.util.ArrayUtil; +import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Modifier; @@ -213,6 +215,57 @@ public class ModifierUtil { public static boolean isInterface(final Class> clazz) { return null != clazz && clazz.isInterface(); } + + /** + * 设置final的field字段可以被修改 + * 只要不会被编译器内联优化的 final 属性就可以通过反射有效的进行修改 -- 修改后代码中可使用到新的值; + *
以下属性,编译器会内联优化,无法通过反射修改:
+ *以下属性,可以通过反射修改:
+ *+ * {@code + * //示例,移除final修饰符 + * class JdbcDialects {private static final List+ * + * @param field 被修改的field,不可以为空 + * @throws UtilException IllegalAccessException等异常包装 + * @author dazer + * @since 5.8.8 + */ + public static void removeFinalModify(final Field field) { + if (null == field || false == hasModifier(field, ModifierUtil.ModifierType.FINAL)) { + return; + } + //将字段的访问权限设为true:即去除private修饰符的影响 + if (false == field.isAccessible()) { + field.setAccessible(true); + } + try { + //去除final修饰符的影响,将字段设为可修改的 + final Field modifiersField = Field.class.getDeclaredField("modifiers"); + //Field 的 modifiers 是私有的 + modifiersField.setAccessible(true); + //& :位与运算符,按位与; 运算规则:两个数都转为二进制,然后从高位开始比较,如果两个数都为1则为1,否则为0。 + //~ :位非运算符,按位取反;运算规则:转成二进制,如果位为0,结果是1,如果位为1,结果是0. + modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); + } catch (final NoSuchFieldException | IllegalAccessException e) { + //内部,工具类,基本不抛出异常 + throw new UtilException(e, "IllegalAccess for {}.{}", field.getDeclaringClass(), field.getName()); + } + } //-------------------------------------------------------------------------------------------------------- Private method start /** diff --git a/hutool-core/src/test/java/cn/hutool/core/util/ModifierUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/ModifierUtilTest.java index fae64188a..a7385ce13 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/ModifierUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/ModifierUtilTest.java @@ -1,10 +1,14 @@ package cn.hutool.core.util; +import cn.hutool.core.reflect.FieldUtil; import cn.hutool.core.reflect.ModifierUtil; import org.junit.Assert; import org.junit.Test; +import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; public class ModifierUtilTest { @@ -20,4 +24,27 @@ public class ModifierUtilTest { private static void ddd() { } + + @Test + public void setFinalFieldValueTest() { + final String fieldName = "DIALECTS"; + final Listdialects = new ArrayList<>();} + * Field field = ReflectUtil.getField(JdbcDialects.class, fieldName); + * ReflectUtil.removeFinalModify(field); + * ReflectUtil.setFieldValue(JdbcDialects.class, fieldName, dialects); + * } + *