所以我在玩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

08-25 13:57
查看更多