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