看一下以下代码:
Long minima = -9223372036854775808L;
Long anotherminima = -9223372036854775808L;
System.out.println(minima==anotherminima); //evaluates to false
System.out.println(Long.MIN_VALUE);
Long another= 1L;
Long one = 1L;
System.out.println(another == one); //evaluates to true
我无法理解这种行为..?我希望第一个eval也是真的.. 这就是我所期待的......
答案 0 :(得分:4)
JVM使用一种缓存技术来处理某些范围的自动装箱值。如规范(http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7)
中所述如果装箱的值p为真,假,字节或范围为\ u0000到\ u007f的字符,或者介于-128和127(含)之间的整数或短数,则让r1和r2为p的任意两次拳击转换的结果。始终是r1 == r2。
的情况理想情况下,装箱给定的原始值p将始终产生相同的参考。实际上,使用现有的实现技术可能不可行。上述规则是一种务实的妥协。上面的最后一个条款要求将某些常见值装入无法区分的对象中。实现可以懒惰地或急切地缓存这些。对于其他值,此公式不允许对程序员的盒装值的身份进行任何假设。这将允许(但不要求)共享部分或全部这些引用。
这确保了在大多数情况下,行为将是所需的行为,而不会造成过度的性能损失,尤其是在小型设备上。例如,较少内存限制的实现可以缓存所有char和short值,以及-32K到+ 32K范围内的int和long值。
因此1L在此缓存值中,然后自动装箱提供完全相同的引用,但是在此范围之外的数字的情况下(如Long.MIN_VALUE),它不会被缓存,因此不同的实例/引用给出了。
在任何情况下,比较对象时都应该使用.equals()
答案 1 :(得分:2)
这里只是一个猜测,但可能是1L在常量池中,因此引用相等性的计算结果为true(就像有时候,甚至通过Strings,==将评估为true),而另一个巨大的号码不是。不知道如何在启动时检查池中的常量。
编辑:Java具有某些常量对象的缓存(包括基元的包装类和String)。因此,如果你写
String st1 = "A";
如果" A"在常量池中,Java不会创建新的String对象 - 它只会创建对现有String对象的引用。所以,如果你那么
String st2 = "A";
System.out.println(st1 == st2);
它会打印出来。
现在,并非所有Integer,Long,Short等都被缓存(有太多的东西),但是值越低。所以我认为1L是。这意味着在您的问题中,another
和one
都引用同一个对象,因此即使引用相等也会返回true。
答案 2 :(得分:2)
首先,您应该使用long
而不是Long
。其次== Integer,Long等将检查引用相等性。您可以查看5.1.7 Boxing Conversion。 Alo 1L
位于常量池中,因此第二种情况返回true。
在旁注中,您应该使用.equals
来比较长。
来自Oracle文档:
如果框中的值p为true,false,则为字节或字符 范围\ u0000到\ u007f,或介于-128和127之间的int或短数字 (包括),然后让r1和r2成为任意两个拳击的结果 转换p。始终是r1 == r2。
的情况理想情况下,装箱给定的原始值p总会产生一个 相同的参考。在实践中,这可能是不可行的 现有的实施技术。上述规则是务实的 妥协。上面的最后一个条款要求某些共同的价值 总是被装入无法区分的物体。 [...]
这确保了在大多数情况下,行为将是 期望的,特别是没有施加过度的性能损失 在小型设备上。对于内存限制较少的实现可能 例如,缓存所有char和short值,以及int和long 值范围为-32K至+ 32K。
答案 3 :(得分:0)
<强>问题:强>
(minima==anotherminima)
您正在比较对象的内存位置而不是其值,因此返回 false 。
如果要比较两个长包装类,则需要调用compareTo
来自jls
If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f,
or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results
of any two boxing conversions of p. It is always the case that r1 == r2.
现在,如果你使用-128和127初始化Long包装器类,它将导致装箱转换,它具有相同的引用。
答案 4 :(得分:0)
添加到this answer,从-128到127的所有内容都缓存到永久java内存中的实例中,这意味着这些数字(几乎)总是具有引用相等性,因为不会为它们创建新实例。在缓存之外,每次使用该数字时都会创建一个新实例,因此它们在引用时不相等。 Read more here和here
答案 5 :(得分:-2)
您应该使用long
代替Long
。请注意,Long
是一个类,因此您必须使用equals()
来比较它的实例。另一方面,如果您使用long
,则可以与==
进行比较,因为这些是基元。