【问题标题】:How "==" works on primitive types“==”如何作用于原始类型
【发布时间】:2016-12-21 17:10:27
【问题描述】:

我想知道“==”运算符如何处理原始值。我知道“==”检查两个引用是否指向堆上的同一个对象。 但是它如何在存储在堆栈中的原始值的上下文中工作? 例如

int a = 5; int b = 5;

我假设这些值没有存储在内存中的同一个位置,但是 a == b 返回“真”。

我的假设是 JVM 将存储在堆栈中的所有值视为存储在内存中的一个位置,并且在“==”的情况下返回 true。 你能更详细地解释一下这件事吗?

问候

【问题讨论】:

  • 你能更清楚你想知道什么吗?你的问题很模糊。
  • 按值比较它们。
  • 你把事情弄得太复杂了。 == 只是比较值。比较地址或假装值存储在内存中的一个位置没有任何意义。

标签: java jvm heap-memory primitive-types stack-memory


【解决方案1】:

你的假设是错误的。在比较原语时,没有内存地址在起作用。这是比较一个值是否等于另一个值的简单指令,在字节码中实现为(寄存器值的)比较和条件跳转。

【讨论】:

    【解决方案2】:

    编辑:正如 James 和 Varun 所指出的,我的原始答案不适用于 OP 的示例,因为对象引用是一个数值,就像整数一样。所以在这种情况下,比较操作实际上是相同的。


    在其他语言中,有一种叫做运算符重载的东西。 Java 不支持用户运算符重载,但了解这些工作原理会让您更好地了解同一个运算符如何根据上下文使用不同的逻辑。

    当您比较变量和原语时,生成的机器代码执行的比较操作与比较两个对象时不同。之所以使用相同的语法,是因为比较的概念在逻辑上足够相似,足以保证使用相同的运算符符号,而不是为两个不同的功能定义完全不同的符号。

    【讨论】:

    • 在处理器的深处,它只是一个比较指令。现在,CMP操作码的不同寻址模式可能取决于cpu架构。在非常基本的模式下,带有索引的帧指针(相对于堆栈变量)将用于读取这两个变量,并生成一个跳转相等或跳转不相等的操作码。
    • 实际上,== 对类整数类型的实现与它对对象引用的实现方式几乎相同,因为对象引用只是一个数字。
    • 詹姆斯和瓦伦你都是对的。我将编辑我的答案以反映这一点。
    【解决方案3】:

    对于任何比较操作,JVM 都会查找操作数的数据类型。根据操作数类型,使用不同的 Java 字节码指令进行比较。

    JVM 适用于两种数据类型。

    根据JVM 7 specification

    与 Java 编程语言一样,Java 虚拟机运行 关于两种类型:原始类型和引用类型。有, 相应地,可以存储在变量中的两种值, 作为参数传递,由方法返回,并对其进行操作:原始 值和参考值。

    引用也是reference 类型的值。

    Java 虚拟机包含对对象的显式支持。一个 object 是动态分配的类实例或数组。一种 对对象的引用被认为具有 Java 虚拟机类型 参考。类型引用的值可以被认为是指向 对象。可能存在对一个对象的多个引用。对象是 始终通过类型引用的值进行操作、传递和测试。

    对于原始类型和引用类型的算术运算,JVM 使用操作码来指定参数的数据类型以及操作。

    例如, lcmp - 比较两个长值

    最后,对于 JVM,任何算术运算都是对给定操作数的字节算术。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-03
      • 1970-01-01
      • 2020-02-27
      • 1970-01-01
      • 1970-01-01
      • 2017-07-18
      • 1970-01-01
      相关资源
      最近更新 更多