Изменение значений логических строк с помощью отражения не работает - PullRequest
3 голосов
/ 04 января 2012

Я экспериментировал с Java-отражением и встроенными строками и придумал результат, который меня смущает.

import java.lang.reflect.Field;

public class HappyDebugging {

    public static void main(String[] args) throws Exception {
        defineTrueFalse();

        System.out.println("true is " + true); // why is it "true is true"?
        System.out.println("false is " + false);
        System.out.println(true);
        System.out.println(false);
        System.out.println("true");
        System.out.println("false");
        System.out.println("true is " + Boolean.valueOf(true));
        System.out.println("false is " + Boolean.valueOf(false));
        System.out.println("true is " + Boolean.valueOf("true"));
        System.out.println("false is " + Boolean.valueOf("false"));
    }

    static void defineTrueFalse() throws Exception{
        Field field = String.class.getDeclaredField("value");
        field.setAccessible(true);
        field.set("true", new char[] {'f', 'a', 'l', 's', 'e'});
        field.set("false", new char[] {'t', 'r', 'u', 'e'});

        field = String.class.getDeclaredField("offset");
        field.setAccessible(true);
        field.setInt("true", 0);
        field.setInt("false", 0);

        field = String.class.getDeclaredField("count");
        field.setAccessible(true);
        field.setInt("true", 5);
        field.setInt("false", 4);
    }
}

Почему первые две строки в выходных данных

true is true
false is false

Я ожидаю, что они будут

true is false
false is true

Обратите внимание, что выходные данные различаются на разных платформах.

Ответы [ 5 ]

17 голосов
/ 30 декабря 2012

это, кажется, работает ....

String.valueOf(BooleanValue)
6 голосов
/ 04 января 2012

В моем компиляторе эти две строки компилируются для использования фактических строк "true is true" и "false is false" (то есть конкатенации во время выполнения не происходит), поэтому ваше отражающее зло приходит слишком поздно. Вы говорите, что вывод зависит от платформы, поэтому я думаю, что некоторые компиляторы не должны выполнять эту оптимизацию.

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

defineTrueFalse не имеет никакого эффекта, поэтому "true is " + true рассматривается как "true is " + Boolean.toString(true), поэтому он дает вам результат как true is true

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

Ответ прост. Эти две строки

 System.out.println("true is " + true);
 System.out.println("false is " + false);

сделайте следующее. 1. простое значение типа boolean "true" преобразуется в строку, что приводит к строке "true" То же самое для "ложного", и это все

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

Потому что вы балуетесь содержимым интернированных строковых литералов (таким образом, я бы добавил, что ваши души будут ввергнуты в вечные страдания в девятом круге ада), но ваши первые две строки объединяют логические литералы, а не строки литералы. Ничто в defineTrueFalse() не влияет на логические значения true и false (в отличие от строковых литералов "true" и "false").

Обратите внимание, что выходные данные различаются для разных платформ.

Но не на первые две строки, я бы поставил. Для вещей, связанных со String, которые могут быть, поскольку поведение зависит от интернирования строковых литералов, что, я не думаю, гарантируется спецификацией (таким образом, девятый круг ада).

...