public static void main(String[] args)
{
Integer a = 126; //no boxed up conversion, new object ref
Integer b = 126; //no boxed up conversion, re-use memory address
System.out.println("Are they equal? " + (a == b)); // true
Integer a1 = 140; //boxed up conversion, new object
Integer b1 = 140; //boxed up conversion, new object
System.out.println("Are they equal? " + (a1 == b1)); // false
System.out.println("Are they equal? " + (new Long(5) == new Long(5))); // false
}
9条答案
按热度按时间hgncfbus1#
编辑:规范对装箱转换做了一些保证。来自5.1.7节:
如果要装箱的值p为true、false、byte、\u0000到\u007f范围内的char,或者-128到127之间的int或short数字,则令r1和r2为p的任意两个装箱转换的结果。r1 == r2总是这种情况。
请注意,该实现 * 可以 * 使用更大的池。
我真的会避免写依赖于它的代码,不是因为它可能会失败,而是因为它不明显--很少有人会那么了解这个规范(我以前认为它是依赖于实现的)。
您应该使用
equals
或比较基础值,即或
请注意,即使自动装箱保证使用固定值,其他调用方也始终可以创建单独的示例。
pes8fvy92#
如果要比较任意两个对象是否相等,请使用
.equals()
。即使(尤其是)这些对象是原语 Package 器类型
Byte
、Character
、Short
、Integer
、Long
、Float
、Double
和Boolean
。对于对象,“
==
“只比较对象的标识,这是非常,非常少的,你想要的,事实上你从来没有用原始 Package 器得到你想要的。仅在以下两种情况之一中使用
==
:1.比较中涉及的所有值都是原语类型(并且优选地不是浮点数)。
1.您确实想知道两个引用是否指向同一个对象(这包括
enum
s的比较,因为在那里值绑定到对象标识)yhqotfr83#
Java语言规范5.1.7:
如果要装箱的值p为true、false、byte、\u0000到\u007f范围内的char,或者-128到127之间的int或short数字,则令r1和r2为p的任意两个装箱转换的结果。r1 == r2总是这种情况。
以及:
讨论
理想情况下,装箱一个给定的原始值p,将总是产生一个相同的引用。在实践中,使用现有的实现技术,这可能是不可行的。上述规则是一个实用的妥协。上述最后一个子句要求某些公共值总是被装箱到不可区分的对象中。实现可以延迟或急切地缓存这些值。
对于其他值,这个公式不允许程序员对装箱值的身份做任何假设。这将允许(但不要求)共享这些引用中的一些或全部。
这确保了在大多数常见情况下,行为将是所需的,而不会造成不适当的性能损失,特别是在小型设备上。例如,内存限制较少的实现可能会缓存所有字符和短整型,以及-32K -+32K范围内的整型和长整型。
因此,在某些情况下==可以工作,而在其他许多情况下则不行。始终使用.equals是为了安全,因为你不能授权(通常)如何获得示例。
如果速度是一个因素(大多数.equals以==比较开始,或者至少他们应该),并且你可以保证他们是如何分配的,并且他们适合上述范围,那么==是安全的。
有些VM可能会增加该大小,但假定语言规范指定的最小大小比依赖特定VM行为更安全,除非您确实需要。
pod7payv4#
输出:
“它们相等吗?0”
答:
不,它们不相等。您必须使用.equals或比较它们的原始值。
vom3gejh5#
equals(Object o)方法的实现几乎总是以
因此即使
==
为真,使用equals
也不会对性能造成太大影响。我建议总是 * 在对象上使用
equals
方法。*当然,有极少数时候你不应该接受这个建议。
mlmc2os56#
一般的答案是no,您不能保证对于相同的数值,您得到的Long对象是相同的(即使您限制自己使用Long.valueOf())。
然而,通过首先尝试测试引用的相等性(使用==),然后,如果失败,尝试equals(),您可能会获得性能改进。这一切都取决于附加的==测试和方法调用的成本比较...您的里程可能会有所不同,但值得尝试一个简单的循环测试,看看哪一个更好。
3pmvbmvn7#
值得注意的是,自动装箱值将使用池化对象(如果它们可用),这就是为什么对于Java 6 u13,(Integer)0 ==(Integer)0,而(Integer)128!=(Integer)128
r8xiu3jd8#
我喜欢直观地看到结果:
mhd8tkvw9#
==
比较对象引用,而equals(Object obj)
比较对象相等性。* 如果存在多个equals对象示例 *,则您必须使用equals
进行相等性比较。示例:
它们是不同的对象示例,但根据Integer的等式是相等的,因此必须使用
equals(Object obj)
在这种情况下,将仅存在
FEMALE
一个示例,因此==
是安全的。