尝试修改私有静态字段时出现 IllegalAccessException

IllegalAccessException when trying to modify private static field

我试着按照这个Change private static final field using Java reflection

但出于某种原因我得到 java.lang.IllegalAccessException: Can not set static final java.lang.Long field DataRepositoryTests.Item.id to java.lang.Integer

for (Field field : Table.getDeclaredFields()){

                    System.out.println(Table.getSimpleName()); //prints "Item"
                    
                    field.setAccessible(true);

                    if (field.getName().equals(GeneratedValueFields.get(i).getName())) { 

                        System.out.println(field.getName()); //prints "id"

                        Field modifiersField = Table.getDeclaredField(GeneratedValueFields.get(i).getName()); 

                        System.out.println(modifiersField.getName()); //prints "id" as expected

                        modifiersField.setAccessible(true);
                        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); //error here

                        //data = 9 (Long)

                        field.set(null,data);


                    };

现在如果我删除行 modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

我得到java.lang.IllegalAccessException: Can not set static final java.lang.Long field DataRepositoryTests.Item.id to java.lang.Long

如果我将字段更改为 private final 并指定对象

field.set(TableModel,data);

正常工作

Change private static final field using Java reflection 中的代码在 Java 1.8 中有效,但在 Java 17 中无效。

在 Java 17 中,jdk.internal.reflect.Reflection class 包含 classes 的映射,其中的部分或全部成员应该对反射不可见:


    /** Used to filter out fields and methods from certain classes from public
        view, where they are sensitive or they may contain VM-internal objects.
        These Maps are updated very rarely. Rather than synchronize on
        each access, we use copy-on-write */
    private static volatile Map<Class<?>, Set<String>> fieldFilterMap;
    ...
    private static final String WILDCARD = "*";
    public static final Set<String> ALL_MEMBERS = Set.of(WILDCARD);

    static {
        fieldFilterMap = Map.of(
            Reflection.class, ALL_MEMBERS,
            ...
        );
        ...
    }

因此该示例不适用于较新的 JDK。

从 Java 12 开始就是这种情况:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8210496