在比较 Java 中的两个原语与两个对象时,== 实际上是相同还是不同?
Posted
技术标签:
【中文标题】在比较 Java 中的两个原语与两个对象时,== 实际上是相同还是不同?【英文标题】:Does == actually work the same or different when comparing two primitives vs two Objects in Java? 【发布时间】:2019-12-23 18:10:09 【问题描述】:在搜索逻辑等于 ==
在 Java 中如何工作的解释时,答案总是如下:
但这些解释似乎都暗示这是 2 种不同的东西,==
的行为不同,具体取决于您是在比较对象还是原语。在我看来,它们实际上一定是完全相同的东西:从堆栈中取出两个变量并比较它们的值。
改变的不是==
的行为,而是它所比较的值所代表的内容。如果您要比较的东西是原语,那么 Stack 上的值就是原语本身的值。如果你在比较对象,那么堆栈上的值就是引用的值(因此是堆上对象的地址)。
我是否误解了某些内容,或者==
在所有情况下的行为实际上都是一样的?如果您可以向我指出有关这在幕后如何真正起作用的文档,则可以加分。
【问题讨论】:
跳过中间人,直接进入权威来源:Java Language Reference § 15.21, Equality Operators。但我认为你的想法是正确的:无论你是在处理数字、布尔值还是引用的比较,它们都归结为值的比较。 从计算机的角度来看,这并不意味着它在做两件不同的事情——这种解释是从人类的角度来看的。 如果你从概念上将Java中的对象引用想象成C中的指针,那么对象引用的内容、值就是一个数字:内存中我们可以找到对象内容的地方。所以,是的,objectX == objectY
类似于比较两个原始整数,从这个意义上说,==
在比较原始值和比较对象引用方面确实表现相同。希望这能让您放心……但正如 Stephen C 的正确答案所解释的那样,真正重要的是 Java 规范定义的行为。
【参考方案1】:
正如其他答案/cmets 所说,在 Java 语言级别,==
运算符语义以独立于实现的方式指定(在JLS 15.21 中)。严格来说,您无法从 JLS 文本中推断出“幕后”的实现细节。您只能说==
的任何符合要求的实现都必须以某种方式表现。
我假设我们讨论的是传统的 JVM,其中引用的实际机器表示是机器地址。可以通过其他方式实现引用;例如使用某种间接寻址机制,例如PIDLAM。
在字节码级别,有许多不同字节码指令根据类型(int
、long
或参考)实现==
的逻辑。但是,比较的语义是相似的。一旦字节码被验证为类型安全,整数和地址就可以进行相同的处理,以便在硬件级别进行==
比较。
在硬件(机器指令)级别==
对原始整数类型和非原始值的工作方式相同。在这两种情况下,它都会执行一条机器指令,比较从寄存器或内存(堆或堆栈)中取出的两个“字”。
JLS 为float
和double
指定的==
语义有点不同,因为特殊值(无穷大和非数字值)需要特殊处理。例如:NaN == NaN 是false
。另请参阅 IEEE 754 浮点标准。
为此有不同的字节码,并且在硬件级别使用的指令与整数和参考案例中使用的指令不同。 (特殊值的处理通常在浮动硬件中处理。)
JLS为boolean
、byte
、short
和char
指定==
的语义是将值提升为另一种类型(int
、long
、float
或@987654342 @) 在比较它们之前。如果操作数具有不同的(未装箱的)类型,则在其他情况下也会发生提升。
此外,如果一个(但不是两个!)操作数被装箱,则会发生拆箱。如果两个操作数都被装箱,则==
是参考比较。
总结以上...
我是否误解了某些内容,或者 == 实际上在所有情况下的行为都相同?
不,如果您包含浮点类型,以及原始扩展和取消装箱的考虑因素,则不会。
如果您可以向我指出有关这在幕后如何真正起作用的文档,则可以加分。
对此没有官方 (Oracle) 公开文档。 JLS 和 JVM 规范没有规定实现策略。
【讨论】:
【参考方案2】:我理解您的解释,并且考虑到某些术语的定义,这是正确的。但它不符合 Java 谈论对象和原语的方式。
Java 中“引用”对象的想法被严重低估了;我认为有可能成为一个“Java 程序员”并没有真正理解什么是引用。你可以记住它产生影响的规则——'==' 运算符,将参数传递给方法——但不明白它是如何实现的,或者可能是如何实现的。
所以我认为许多使用 Java 编程的人说 == '在所有情况下都表现相同' 会让人感到困惑,因为这涉及到太多的“幕后”知识。 Java 不鼓励您(或要求您)在这种程度上“隐藏”。
【讨论】:
以上是关于在比较 Java 中的两个原语与两个对象时,== 实际上是相同还是不同?的主要内容,如果未能解决你的问题,请参考以下文章