From 9c72b8cda4102b68df3f07523b6f5b781b8cd78b Mon Sep 17 00:00:00 2001 From: Marc Baloup Date: Sun, 24 Nov 2024 16:18:14 +0100 Subject: [PATCH] Properly handle setting final fields in reflection API --- .../pandacube/lib/reflect/ReflectField.java | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/pandalib-reflect/src/main/java/fr/pandacube/lib/reflect/ReflectField.java b/pandalib-reflect/src/main/java/fr/pandacube/lib/reflect/ReflectField.java index 1ded3b8..d5c2d25 100644 --- a/pandalib-reflect/src/main/java/fr/pandacube/lib/reflect/ReflectField.java +++ b/pandalib-reflect/src/main/java/fr/pandacube/lib/reflect/ReflectField.java @@ -9,7 +9,7 @@ import java.lang.reflect.Modifier; */ public final class ReflectField extends ReflectMember { - /* 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. */ private static sun.misc.Unsafe sunMiscUnsafeInstance; @@ -122,13 +122,30 @@ public final class ReflectField extends ReflectMember= 16 // set the value of the field, directly in the memory - if (Modifier.isStatic(realModifiers)) { - long offset = sunMiscUnsafeInstance.staticFieldOffset(f); - sunMiscUnsafeInstance.putObject(sunMiscUnsafeInstance.staticFieldBase(f), offset, value); - } else { - long offset = sunMiscUnsafeInstance.objectFieldOffset(f); - sunMiscUnsafeInstance.putObject(instance, offset, value); - } + Object unsafeObjInstance = Modifier.isStatic(realModifiers) + ? sunMiscUnsafeInstance.staticFieldBase(f) + : instance; + long offset = Modifier.isStatic(realModifiers) + ? sunMiscUnsafeInstance.staticFieldOffset(f) + : 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 // change the modifier in the Field instance so the method #set(instance, value) doesn't throw an exception try {