String是final不可变的,确定不可变吗?通过骚操作,让你产生怀疑~

297 阅读1分钟

呈上骚操作代码

发现这个问题,还是因为同事在写Spring Aop的时候,需要对某些参数进行加解密,他在测试的时候,发现固定的String字符串是上一次加密后的字符串,而通过debug显示的是字符串本身,但是却不是。 如下是简要后的代码:

import java.lang.reflect.Field;

public class TestStr {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        String str = "HelloWorld";
        testReflect(str, null);
        System.out.println(str);
        String str1 = "HelloWorld";
        testReflect(str, "HelloGo");
        System.out.println(str1);
    }

    private static void testReflect(String str, String newValue) throws NoSuchFieldException, IllegalAccessException {
        Class<? extends String> strClass = str.getClass();
        Field value = strClass.getDeclaredField("value");
        value.setAccessible(true);
        value.set(str, null == newValue ? "HelloSpring".toCharArray() : newValue.toCharArray());
    }
}

debug后的图,如下:

原始值

更改后的值

出现这种情况的原因是,通过反射强制修改了String中value char[]数组的引用

通过反射修改的引用