2 回答
TA贡献1887条经验 获得超5个赞
在 Java 语言级别,==
运算符语义以独立于实现的方式指定(在JLS 15.21中)。严格来说,您不能从 JLS 文本中推断出“幕后”实现细节。您只能说,任何符合规范的实现都==
必须以某种方式运行。
我假设我们正在谈论传统的 JVM,其中引用的实际机器表示是机器地址。可以通过其他方式实现引用;例如,使用某种间接寻址机制,例如PIDLAM。
在字节码级别,有许多不同的==
字节码指令实现了依赖于类型(int
,或引用)的逻辑long
。但是,比较的语义是相似的。一旦字节码被验证为类型安全的,为了在硬件级别进行比较,就可以对整数和地址进行相同的处理。==
在硬件(机器指令)级别,==
原始整数类型和非原始值的工作方式相同。在这两种情况下,它将执行一条机器指令,该指令比较从寄存器或内存(堆或堆栈)中获取的两个“字”。
JLS 指定的==
forfloat
和的语义double
有点不同,因为特殊值(无穷大和非数字值)需要特殊处理。例如:NaN == NaN 是false
. 另请参阅 IEEE 754 浮点标准。
为此有不同的字节码,并且在硬件级别使用的指令与整数和参考案例中使用的指令不同。(特殊值的处理通常在浮动硬件中处理。)
JLS 指定了==
for boolean
、和 is的语义byte
,以便在比较它们之前将值提升为另一种类型(、或) 。如果操作数具有不同的(未装箱的)类型,则提升也会发生在其他情况下。 short
char
int
long
float
double
此外,如果一个(但不是两个!)操作数被装箱,则会发生拆箱。如果两个操作数都被装箱,则为==
引用比较。
总结以上...
我是不是误解了什么,或者 == 实际上在所有情况下都表现得一样?
不,如果您包括浮点类型,以及原始加宽和拆箱的注意事项,则不会。
如果你能给我指出这在幕后是如何工作的文档,那就加分了。
没有关于此的官方(Oracle)公共文档。JLS 和 JVM 规范没有规定实现策略。
TA贡献1921条经验 获得超9个赞
我理解你的解释,并且给出某些术语的定义是正确的。但它不符合 Java 谈论对象和原语的方式。
在 Java 中“引用”对象的想法被严重低估了;我认为有可能成为一名“Java 程序员”却并不真正了解什么是引用。您可以记住它产生影响的规则——“==”运算符,将参数传递给方法——而不理解它是如何实现的,或者可能是如何实现的。
所以我认为许多使用 Java 编程的人会感到困惑,因为说 == “在所有情况下都表现相同”,因为这涉及太多“幕后”知识。Java 不鼓励您(或要求您)在那种程度上“深入了解”。
添加回答
举报