Читал сейчас статью и решил протестировать код оттуда.
import java.lang.reflect.Field;

public class DeduplicationDemo {

    public static void main(String[] args) throws InterruptedException, NoSuchFieldException, IllegalAccessException {
        char[] chars = {'T', 'o', 'p', 'J', 'a', 'v', 'a'};
        String[] strings = {new String(chars), new String(chars)};
        Field value = String.class.getDeclaredField("value");
        value.setAccessible(true);

        System.out.println("Хеш первого объекта: " + value.get(strings[0]));
        System.out.println("Хеш второго объекта: " + value.get(strings[1]));

        System.gc();
        System.out.println("Запустили сборщик мусора");
        Thread.sleep(100);

        System.out.println("Хеш первого объекта: " + value.get(strings[0]));
        System.out.println("Хеш второго объекта: " + value.get(strings[1]));
    }
}
Но столкнулся с таким выводом
Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make field private final byte[] java.lang.String.value accessible: module java.base does not "opens java.lang" to unnamed module @119d7047
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:357)
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
	at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:177)
	at java.base/java.lang.reflect.Field.setAccessible(Field.java:171)
	at Test.main(Test.java:9)
Почитав про метод setAccessible, понял, что он не дает себя использовать для final полей. А массив value как раз является final. Именно из-за этого же возникает ошибка? Просто странно, в статье у них работает корректный вывод.