我被告知永远不要使用==
字符串,而是用于其他所有内容,因为.equals
会比较值而不是对象的实例。(我理解的区别)。
根据某些网站,==
比较内存位置?
我不明白的是,如果您将一个整数与另一个进行比较,为什么要比较内存位置,或者这只是用于字符串?
如果您将 int 3 与 int 4 进行比较,显然它不会位于同一内存位置,但是如果您将 int 4 与 int 4 进行比较,这是否意味着所有值为 4 的整数都存储在同一个内存位置内存位置?
我被告知永远不要使用==
字符串,而是用于其他所有内容,因为.equals
会比较值而不是对象的实例。(我理解的区别)。
根据某些网站,==
比较内存位置?
我不明白的是,如果您将一个整数与另一个进行比较,为什么要比较内存位置,或者这只是用于字符串?
如果您将 int 3 与 int 4 进行比较,显然它不会位于同一内存位置,但是如果您将 int 4 与 int 4 进行比较,这是否意味着所有值为 4 的整数都存储在同一个内存位置内存位置?
根据某些网站,
==
比较内存位置?
该表达式a == b
比较 和 的内容,a
而b
不管它们的类型。
我不明白的是,如果您将一个整数与另一个进行比较,为什么要比较内存位置,或者这只是用于字符串?
如果a
和b
是引用,==
操作员将比较“内存位置”,因为这是变量包含的内容。
如果a
和b
是原始类型,例如int
或double
变量将包含实际值,则将比较这些值(而不是它们的位置)。
(请注意,变量永远不能包含诸如 a 之类的对象String
,它最多可以指向一个对象。)
这是否意味着所有值为 4 的整数都存储在同一个内存位置?
不。如上所述,int
s 是“直接”比较的。当谈到Integer
故事时,情况略有不同。首先new
保证你得到一个新的参考,那就是
Object i = new Integer(5);
Object j = new Integer(5);
... i == j ...
将始终产生错误。
但是,如果您通过自动装箱:
Object i = (Integer) 5;
Object j = (Integer) 5;
... i == j ...
由于自动装箱会通过缓存以获取 -128-127 范围内的值,因此您会得到正确的结果。(例如看这个问题:比较两个整数:为什么 == true?)
== 比较操作数的值是原始类型还是引用类型。
如果操作数是原始的,则将比较操作数的值。
作为引用的操作数包含值,即访问它们所引用的对象的地址。String 不是原始数据类型,它们在 java 中被视为对象,当您比较两个 string 类型的引用时,只有当操作数的值(即 String 对象的地址)相等时,结果才会为真(这意味着它们引用到同一个 String 对象)。
简而言之:事情是int
原始类型,而String
对象是对象。可以比较原始类型的值,==
因为变量指向值本身而不是对值的引用。
int
's 是 java 中的原始类型,因此它们不代表对象“引用”,而是直接代表值。
== 比较引用类型。int 是原始类型。
所以:
int x = 3;
int y = 3;
x==y is true
但使用整数引用类型
Integer x = new Integer(3);
Integer y = new Integer(3);
x == y is false
== 运算符比较内存中对象的引用,而字符串是对象 - 基元不是对象,只要它们属于同一类型,那么 == 就可以工作。正如您所说,如果它们是基元的对象变体(例如整数表示 int),那么 java (>5) 自动装箱以便进行比较。
来自 Java Specification 15.21 Equality Operators:
15.21 等式运算符
等式运算符在语法上是左结合的(它们从左到右分组),但这个事实本质上是没有用的;例如,a==b==c 解析为 (a==b)==c。a==b 的结果类型始终是布尔值,因此 c 必须是布尔类型,否则会发生编译时错误。因此,a==b==c 不会测试 a、b 和 c 是否都相等。
EqualityExpression: RelationalExpression EqualityExpression == RelationalExpression EqualityExpression != RelationalExpression ==(等于)和!=(不等于)运算符类似于关系运算符,只是它们的优先级较低。因此,一个
在所有情况下,a!=b 产生与 !(a==b) 相同的结果。如果操作数表达式没有副作用,则等式运算符是可交换的。
15.21.1 数值等式运算符 == 和 !=
如果相等运算符的操作数都是数字类型,或者一个是数字类型而另一个是可转换的(第 5.1.8 节)为数字类型,则对操作数执行二进制数字提升(第 5.6.2 节)。如果操作数的提升类型是 int 或 long,则执行整数相等测试;如果提升的类型是 float 或 double,则执行浮点相等测试。请注意,二进制数字提升执行值集转换(第 5.1.13 节)和拆箱转换(第 5.1.8 节)。对浮点值进行准确的比较,无论它们的表示值来自哪个值集。
浮点相等性测试根据 IEEE 754 标准的规则执行:
如果任一操作数为 NaN,则 == 的结果为假,但 != 的结果为真。实际上,当且仅当 x 的值为 NaN 时,测试 x!=x 为真。(Float.isNaN 和 Double.isNaN 方法也可用于测试值是否为 NaN。)正零和负零被认为是相等的。因此,例如,-0.0==0.0 为真。否则,相等运算符认为两个不同的浮点值不相等。特别是,有一个值表示正无穷大,一个值表示负无穷大;each 仅与自身比较相等,并且 each 与所有其他值比较不相等。根据浮点数的这些考虑,以下规则适用于整数操作数或除 NaN 以外的浮点操作数:如果左侧操作数的值等于右侧操作数的值,则 == 运算符生成的值为真;否则,结果为假。如果左侧操作数的值不等于右侧操作数的值,则 != 运算符生成的值为真;否则,结果为假。15.21.2 布尔等式运算符 == 和 !=
如果相等运算符的操作数都是布尔类型,或者如果一个操作数是布尔类型而另一个是布尔类型,则该操作是布尔相等。布尔相等运算符是关联的。如果其中一个操作数是布尔类型,则它会进行拆箱转换(第 5.1.8 节)。
如果操作数(在任何所需的拆箱转换之后)都为真或都为假,则 == 的结果为真;否则,结果为假。
如果操作数都为真或都为假,!= 的结果为假;否则,结果为真。因此,当应用于布尔操作数时,!= 的行为与 ^(第 15.22.2 节)相同。
15.21.3 引用相等运算符 == 和 !=
如果相等运算符的操作数既是引用类型又是 null 类型,则该操作是对象相等。如果无法通过强制转换(第 5.5 节)将任一操作数的类型转换为另一个操作数的类型,则会发生编译时错误。两个操作数的运行时值必然不相等。
在运行时,如果操作数的值都为 null 或都引用同一个对象或数组,则 == 的结果为真;否则,结果为假。
如果操作数的值都为 null 或都引用同一个对象或数组,则 != 的结果为 false;否则,结果为真。
虽然 == 可用于比较 String 类型的引用,但这样的相等性测试确定两个操作数是否引用相同的 String 对象。如果操作数是不同的 String 对象,则结果为 false,即使它们包含相同的字符序列。可以通过方法调用 s.equals(t) 来测试两个字符串 s 和 t 的内容是否相等。另见§3.10.5。
==
运算符按值比较s ,int
按地址比较对象。因此,==
对于 s 是正确的,int
但(通常)对于String
s 是不正确的。
请注意,如果您知道该方法String
已返回两个 s ,则可以正常工作,因为可以保证为相同的字符串返回相同的地址。String.intern
==
intern
对象在值上是相等的,但对象的值是对内存位置的引用。原语(即 int、boolean、char、double)不使用引用,而是存储它们的值。所以当使用 == 时,它会比较两者的值。在对象的情况下,它是一个参考;然而,在原语的情况下,它是它存储的值。