JAVA反射修改static,final修饰的变量
1. 调⽤对应Class的getDeclaredField或getField⽅法,获取要修改的Filed;
2个⽅法的差别在于:
getDeclaredField可获取当前Class内所有变量名(private,protect,public,friend),但不会获取⽗类变量;
getField可获取当前Class及⽗Class内所有访问级别为public的变量名;
2. final修饰的常量不可修改,判断field对应数据为常量则直接返回false;
常量的判断条件:
1)使⽤了final修饰
2)数据类型为基本类型或者String类型
原因:
使⽤final修饰后,被引⽤的数据地址将不可改变,我们只能尝试修改地址上的内容,⽽常量不能修改地址内容,或者说修改不⽣效。
3. 如果访问级别不是public,调⽤setAccessible(true)获得访问权限;
4. 如果使⽤了final修饰,⽽没有使⽤static修饰,可以调⽤setAccessible(true)获得修改权限,或者修改Modifier,去除final修饰符;
如果同时使⽤了static和final,则只能通过修改Modifier去除final修饰符来获取修改权限;
5. 判断要修改的数据类型,如果为基本类型,调⽤对应的基本类型修改⽅法,其他情况直接调⽤set⽅法;
6. 对修改过的部分还原。
综合上述步骤,对应代码如下:
public static boolean setValue(@Nullable Object source, @NonNull Class<?> target,
@NonNull String name, @Nullable Object value) {
Field field = null;
int modify = 0;
Field modifiersField = null;
boolean removeFinal = false;
try {
field = DeclaredField(name);
modify = Modifiers();
//final修饰的基本类型不可修改
if (Type().isPrimitive() && Modifier.isFinal(modify)) {
return false;
}
/
/获取访问权限
if (!Modifier.isPublic(modify) || Modifier.isFinal(modify)) {
field.setAccessible(true);
}
//static final同时修饰
removeFinal = Modifier.isStatic(modify) && Modifier.isFinal(modify);
if (removeFinal) {
modifiersField = DeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, modify & ~Modifier.FINAL);
}
/
/按照类型调⽤设置⽅法
if (value != null && Type().isPrimitive()) {
if ("int".Type().getName()) && value instanceof Number) {
field.setInt(source, ((Number) value).intValue());
} else if ("boolean".Type().getName()) && value instanceof Boolean) {
field.setBoolean(source, (Boolean) value);
} else if ("byte".Type().getName()) && value instanceof Byte) {
field.setByte(source, (Byte) value);
} else if ("char".Type().getName()) && value instanceof Character) {
field.setChar(source, (Character) value);
} else if ("double".Type().getName()) && value instanceof Number) {
field.setDouble(source, ((Number) value).doubleValue());
} else if ("long".Type().getName()) && value instanceof Number) {
field.setLong(source, ((Number) value).longValue());
} else if ("float".Type().getName()) && value instanceof Number) {
field.setFloat(source, ((Number) value).floatValue());
} else if ("short".Type().getName()) && value instanceof Number) {
field.setShort(source, ((Number) value).shortValue());
} else {
return false;
}
} else {
field.set(source, value);
}
} catch (Exception e) {
return false;
} finally {
try {
//权限还原
if (field != null) {
if (removeFinal && modifiersField != null) {
modifiersField.setInt(field, Modifiers() & ~Modifier.FINAL);
modifiersField.setAccessible(false);
}
if (!Modifier.isPublic(modify) || Modifier.isFinal(modify)) {                        field.setAccessible(false);
}
}
} catch (IllegalAccessException e) {
//
}
java反射获取父类属性}
return true;
}
2020-06-18