java - Boolean.FALSE 不等于 false

标签 java reflection

所以我正在玩 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) 它打印“false”。

请你解释一下吗?

最佳答案

不存在错误,您覆盖的 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() 由于您的反射覆盖 返回true。由于 true == false 你得到 false。这可以是 通过在 Boolean.booleanValue() 中放置断点进行确认。

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

    虽然您确实从上面的比较中得到 false,但它会被自动装箱为 Boolean 以匹配 System.out.format(String, Object...) 方法签名。由于您的反射覆盖,这将输出 true

关于java - Boolean.FALSE 不等于 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54517195/

相关文章:

java - 循环语句逻辑

java - 读取整数文本文件并将其打印到屏幕上

c# - 为元组创建泛型

java - newInstance() 与新的

c++ - 在 C++ 结构中提供代码提示/标签,就像在 Golang 中一样

java - 无法为跟踪文件 .lastUpdated 创建父目录

java - 如何通过仅编辑一个类文件中的一些硬编码 key 来重新编译Java程序?

java - 根据 ID 和列表中的另一个 ID 查找记录

c# - 查找并调用通用重载方法

Java 反射和重构的痛苦