所以我在玩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”。
请您解释一下?
答案 0 :(得分:0)
当您使用System.out.println(false)时,它会显示“ false”。
此布尔值永远不会自动装箱,因此您通过反射进行的更改不相关。
这是调用堆栈:
thing_ids = []
for thing in Thing.objects.all():
status = thing.status_set.last()
if status is not None and status.value == 'bar':
thing_ids.append(thing.id)
queryset = Thing.objects.filter(id__in=thing_ids)
PrintStream::println(boolean x)
PrintStream::print(boolean b)
String::valueOf(boolean b)
的实现方式如下:
String.valueOf(boolean)
因此,您已经更改了包装器类使用的常量这一事实没有任何区别。我们从不使用包装器类。
当我尝试这个System.out.println(Boolean.FALSE == false)时 打印“假”。
public static String valueOf(boolean b) {
return b ? "true" : "false";
}
会自动取消装箱到原始Boolean.FALSE
中。 true
是错误的。
答案 1 :(得分:0)
没有错误,您重写的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
。