samedi 18 juin 2022

Why cannot modify a String field with Reflection?

JDK version: 1.8.0_291

Target class:

package reflectionStackoverflow.test;

public class ClassA {
    private final static StringBuilder nameStringBuilder = new StringBuilder("1");
    private final static String nameString = "1";
 
    public static void printNameStringBuild() {
        System.out.println("nameStringBuilder: " + nameStringBuilder);
    }
    public static void printNameString() {
        System.out.println("nameString: " + nameString);
    }
}

Test Code:

package reflectionStackoverflow.test;

import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class ReflectionTest {
    @Test
    public void test() throws NoSuchFieldException, IllegalAccessException, InstantiationException {
        Class c = ClassA.class;

        Field nameStringBuilder = c.getDeclaredField("nameStringBuilder");
        nameStringBuilder.setAccessible(true);
        Field nameStringBuilderModifiers = nameStringBuilder.getClass().getDeclaredField("modifiers");
        nameStringBuilderModifiers.setAccessible(true);
        nameStringBuilderModifiers.setInt(nameStringBuilder, nameStringBuilder.getModifiers() & ~Modifier.FINAL);
        nameStringBuilder.set(c, new StringBuilder("2"));
        nameStringBuilderModifiers.setInt(nameStringBuilder, nameStringBuilder.getModifiers() & ~Modifier.FINAL);

        Field nameString = c.getDeclaredField("nameString");
        nameString.setAccessible(true);
        Field nameStringModifiers = nameString.getClass().getDeclaredField("modifiers");
        nameStringModifiers.setAccessible(true);
        nameStringModifiers.setInt(nameString, nameString.getModifiers() & ~Modifier.FINAL);
        nameString.set(c, "2");
        nameStringModifiers.setInt(nameString, nameString.getModifiers() & ~Modifier.FINAL);

        ClassA.printNameStringBuild();
        ClassA.printNameString();
    }
}

Test result:

nameStringBuilder: 2
nameString: 1

Conclusion:

StringBuilder field can be modified with reflection, but String field can not be modified.

Question:

Why String can not be modified with reflection?

Is there any way to modify a private final static String value like above StringBuilder case?





Aucun commentaire:

Enregistrer un commentaire