Сбой JVM при попытке изменить значение String с помощью отражения - PullRequest
2 голосов
/ 06 декабря 2010

Это мой первый вопрос, я надеюсь, я не совершу ужасной ошибки. Предполагая, что SecurityManager не мешает мне сделать это:

public static void main(String[] args) {
    String str = "1";
    System.out.println("str value before invoke fillStringValueWithX method: " + str);
    fillStringValueWithX(str);
    System.out.println("str value before invoke fillStringValueWithX method: " + str);
}

private static void fillStringValueWithX(String str) {
    if (str != null) {
        try {
        Field fieldValue = String.class.getDeclaredField("value");
        fieldValue.setAccessible(true);
        char[] charValue = (char[]) fieldValue.get(str);
        Arrays.fill(charValue, 'x');
        fieldValue.setAccessible(false);
        } catch (Exception e) {}
    }
}

Если размер строки равен 1 (пример выше), сбой JVM (дамп сбоя показывает ошибку EXCEPTION_ACCESS_VIOLATION), однако, если размер строки больше 1, этот фрагмент кода работает для меня.

Примечание: Я предполагаю, что подходящее использование для установки значения поля с помощью отражения использует valueField.set(obj, value) Метод поля, но я хочу знать, почему происходит сбой JVM ...

Спасибо

Ответы [ 2 ]

3 голосов
/ 06 декабря 2010

Пациент: Доктор, доктор, мне больно, когда я делаю это ( ударяет рукой молотком ).

Доктор: Тогда не делайте этого.

Вына самом деле не должно пытаться связываться с содержимым строки.Строки предназначены для неизменяемости.Теперь я осмелюсь сказать, что это ошибка JVM, которая так резко падает (этого не происходит на моем компьютере, кстати - было бы полезно, если бы вы сказали нам, какую операционную систему и версию JVM вы используете), но простой ответ:не пытаться идти за спиной системы.

0 голосов
/ 04 января 2012

похоже, что этот массив символов для "1" и ряда других внутренних строк (например, "true", "false", "root", "class" и т. Д.) Нельзя изменить в JVM Windows. То есть Вы не можете назначать новые значения элементам массива. Но вы можете назначить новый массив для этого объекта String. Пример

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...