试图修改私有静态字段时出现非法访问异常



我试图使用Java反射遵循这个Change private static final字段

但由于某种原因,我得到了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

如果我将字段更改为私有最终字段并指定一个对象

field.set(TableModel,data);

工作正常

使用Java反射的Change private static final字段中的代码在Java 1.8中有效,但在Java 17中无效。

在Java17中,jdk.internal.reflect.Reflection类包含一个类的映射,这些类的一些或所有成员应该对反射不可见:


/** 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

最新更新