Properly handle setting final fields in reflection API
This commit is contained in:
parent
ee023b5d2c
commit
9c72b8cda4
@ -9,7 +9,7 @@ import java.lang.reflect.Modifier;
|
|||||||
*/
|
*/
|
||||||
public final class ReflectField<T> extends ReflectMember<T, String, Field, NoSuchFieldException> {
|
public final class ReflectField<T> extends ReflectMember<T, String, Field, NoSuchFieldException> {
|
||||||
|
|
||||||
/* Those fields are used to modify the value of a static variable. Depending on the current Java version,
|
/* Those fields are used to modify the value of a final variable. Depending on the current Java version,
|
||||||
* one of them will be used for this purpose.
|
* one of them will be used for this purpose.
|
||||||
*/
|
*/
|
||||||
private static sun.misc.Unsafe sunMiscUnsafeInstance;
|
private static sun.misc.Unsafe sunMiscUnsafeInstance;
|
||||||
@ -122,13 +122,30 @@ public final class ReflectField<T> extends ReflectMember<T, String, Field, NoSuc
|
|||||||
// if the field is final, we have to do some unsafe stuff :/
|
// if the field is final, we have to do some unsafe stuff :/
|
||||||
if (sunMiscUnsafeInstance != null) { // Java >= 16
|
if (sunMiscUnsafeInstance != null) { // Java >= 16
|
||||||
// set the value of the field, directly in the memory
|
// set the value of the field, directly in the memory
|
||||||
if (Modifier.isStatic(realModifiers)) {
|
Object unsafeObjInstance = Modifier.isStatic(realModifiers)
|
||||||
long offset = sunMiscUnsafeInstance.staticFieldOffset(f);
|
? sunMiscUnsafeInstance.staticFieldBase(f)
|
||||||
sunMiscUnsafeInstance.putObject(sunMiscUnsafeInstance.staticFieldBase(f), offset, value);
|
: instance;
|
||||||
} else {
|
long offset = Modifier.isStatic(realModifiers)
|
||||||
long offset = sunMiscUnsafeInstance.objectFieldOffset(f);
|
? sunMiscUnsafeInstance.staticFieldOffset(f)
|
||||||
sunMiscUnsafeInstance.putObject(instance, offset, value);
|
: sunMiscUnsafeInstance.objectFieldOffset(f);
|
||||||
}
|
if (char.class.isAssignableFrom(f.getType()))
|
||||||
|
sunMiscUnsafeInstance.putChar(unsafeObjInstance, offset, (char)value);
|
||||||
|
else if (byte.class.isAssignableFrom(f.getType()))
|
||||||
|
sunMiscUnsafeInstance.putByte(unsafeObjInstance, offset, (byte)value);
|
||||||
|
else if (short.class.isAssignableFrom(f.getType()))
|
||||||
|
sunMiscUnsafeInstance.putShort(unsafeObjInstance, offset, (short)value);
|
||||||
|
else if (int.class.isAssignableFrom(f.getType()))
|
||||||
|
sunMiscUnsafeInstance.putInt(unsafeObjInstance, offset, (int)value);
|
||||||
|
else if (long.class.isAssignableFrom(f.getType()))
|
||||||
|
sunMiscUnsafeInstance.putLong(unsafeObjInstance, offset, (long)value);
|
||||||
|
else if (boolean.class.isAssignableFrom(f.getType()))
|
||||||
|
sunMiscUnsafeInstance.putBoolean(unsafeObjInstance, offset, (boolean)value);
|
||||||
|
else if (float.class.isAssignableFrom(f.getType()))
|
||||||
|
sunMiscUnsafeInstance.putFloat(unsafeObjInstance, offset, (float)value);
|
||||||
|
else if (double.class.isAssignableFrom(f.getType()))
|
||||||
|
sunMiscUnsafeInstance.putDouble(unsafeObjInstance, offset, (double)value);
|
||||||
|
else
|
||||||
|
sunMiscUnsafeInstance.putObject(unsafeObjInstance, offset, value);
|
||||||
} else { // Java < 16
|
} else { // Java < 16
|
||||||
// change the modifier in the Field instance so the method #set(instance, value) doesn't throw an exception
|
// change the modifier in the Field instance so the method #set(instance, value) doesn't throw an exception
|
||||||
try {
|
try {
|
||||||
|
Loading…
Reference in New Issue
Block a user