Boolean.FALSE не равно ложному - PullRequest
       0

Boolean.FALSE не равно ложному

0 голосов
/ 04 февраля 2019

Итак, я играл с java.lang.reflect и пытался создать что-то вроде this .И вот моя проблема (возможно, ошибка):

Код моего метода для установки поля в true:

private static void setFinalStatic(Field field, Object newValue) throws Exception
{
    field.setAccessible(true);
    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    field.set(null, newValue);
}

Код, где я его печатаю:

setFinalStatic(Boolean.class.getField("FALSE"), true);
System.out.format("%s\n", false);         //prints true
System.out.println(false);                //prints false
System.out.format("%s\n", Boolean.FALSE); //prints true
System.out.println(Boolean.FALSE);        //prints true
System.out.println(Boolean.FALSE == false);        //prints false
System.out.format("%s\n", Boolean.FALSE == false); //prints true

Когда вы используете System.out.format("%s", false), он возвращает «true», как и ожидалось

, но когда вы используете System.out.println(false), он печатает «false».

И когда я пытался это System.out.println(Boolean.FALSE == false) напечатано «ложь».

Вы, пожалуйста, объясните это?

Ответы [ 2 ]

0 голосов
/ 04 февраля 2019

Нет ошибки, Boolean.FALSE, которую вы переопределили, используется для автобокса, потому что boolean автобокс реализован компилятором, беззвучно вызывающим метод Boolean.valueOf() со следующим телом:

public static Boolean valueOf(boolean b) {
    return (b ? TRUE : FALSE);
}

В вашем примере boolean параметры, переданные методам, использующим тип Object, например, System.out.format(String, Object...), будут подвергаться автоматической упаковке.Они будут затронуты вашим отражением изменений и false станет true.

В противном случае методы, использующие примитив boolean, не будут затронуты, например, System.out.println(boolean) и false останутся false.

Две наиболее интересные строки в вашем примере:

  • System.out.println(Boolean.FALSE == false)

    Компилятор распаковывает Boolean.FALSE, вызывая Boolean.FALSE.booleanValue(), который из-за переопределения вашего отражения возвращает truetrue == false вы получите false.Это можно подтвердить, установив точку останова в Boolean.booleanValue().

  • System.out.format("%s\n", Boolean.FALSE == false)

    Хотя вы получите false из сравнения, как указано выше, оно будетбыть автоматически помещенным в Boolean в соответствии с сигнатурой метода System.out.format(String, Object...).Это выведет true из-за переопределения вашего отражения.

0 голосов
/ 04 февраля 2019

когда вы используете System.out.println (false), он печатает «false».

Это логическое значение никогда не блокируется автоматически, поэтому изменение, которое вы вносите с помощью отражения, не имеет значения.

Вот стек вызовов:

PrintStream::println(boolean x)
PrintStream::print(boolean b)
String::valueOf(boolean b)

String.valueOf(boolean) реализован так:

public static String valueOf(boolean b) {
    return b ? "true" : "false";
}

Итак, тот факт, что вы изменили константу, используемуюкласс-обертка не имеет значения.Мы никогда не используем класс-оболочку.

И когда я попробовал этот System.out.println (Boolean.FALSE == false), он напечатал «false».

Boolean.FALSE автоматически распаковывается в примитив true.true == false ложно.

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