= =如何比较内存位置?

时间:2011-11-11 14:22:23

标签: java equals autoboxing

我被告知不要将==用于字符串,而是用于其他所有内容,因为.equals会比较值而不是对象的实例。 (我理解其中的区别)。

根据某些网站,==比较了内存​​位置?

我不明白的是,如果你要将一个整数与另一个整数进行比较,为什么它会比较内存位置,还是仅仅用于字符串?

如果你将int 3与int 4进行比较,显然它不会在同一个内存位置,但是如果你将int 4与int 4进行比较,那是否意味着存储了值为4的所有整数在相同的内存位置?

9 个答案:

答案 0 :(得分:12)

  

根据某些网站,==比较内存位置?

表达式a == b会比较ab内容,无论其类型如何。

  

我不明白的是,如果你要将一个整数与另一个整数进行比较,为什么它会比较内存位置,还是仅仅用于字符串?

如果ab是引用,==运算符将比较“内存位置”,因为这是变量包含的内容。

如果ab属于基本类型,例如intdouble,则变量将包含实际值,因此这些值(而不是其位置)将进行比较。

(请注意,变量永远不能包含对象,例如String,它最多只能指向对象。)

  

这是否意味着值为4的所有整数都存储在同一个内存位置?

没有。如上所述,int被“直接”比较。谈到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范围内的值。 (例如,请参阅此问题:Compare two Integer: why is == true?

答案 1 :(得分:4)

==比较oparands的值,无论它是原始值还是引用类型。

  1. 如果操作数是原始的,则将比较操作数的值。

  2. 作为引用的操作数包含值,即访问它们所引用的对象的地址。字符串不是原始数据类型,它们在java中被视为对象,当您比较两个类型字符串的引用时,只有当操作数的值即String对象的地址相等时,结果才为真(这意味着它们引用到同一个String对象)。

答案 2 :(得分:2)

简单地说:问题是int是原始类型,而String是对象。原始类型的值可以与==进行比较,因为变量指向值本身而不是对值的引用。

答案 3 :(得分:1)

int是java中的原始类型,因此它们不代表对象“引用”,而是直接表示值。

答案 4 :(得分:1)

==比较参考类型。 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

答案 5 :(得分:1)

==运算符比较内存中对象的引用,而字符串是对象 - 原语不是对象,只要它们属于同一类型,那么==就可以工作。如你所说,如果它们是基元的对象变体(例如int的Integer),则java(> 5)自动装箱以进行比较。

答案 6 :(得分:0)

==运算符按值和对象按地址比较int。因此,==对于int是正确的,但(通常)不适用于String s。

请注意,如果您知道String方法已返回String.intern==,则intern可正常工作,因为{{1}}保证返回相同的地址相同的字符串。

答案 7 :(得分:0)

来自Java规范15.21 Equality Operators

  

15.21平等操作员

     

等于运算符在语法上是左关联的(它们是组合的   从左到右),但这个事实基本上没有用;对于   例如,a == b == c解析为(a == b)== c。 a == b的结果类型是   总是布尔值,因此c必须是boolean或a的类型   发生编译时错误。因此,a == b == c不测试是否   a,b和c都是相等的。

     

EqualityExpression:           RelationalExpression           EqualityExpression == RelationalExpression           EqualityExpression!= RelationalExpression ==(等于)和!=(不等于)运算符类似于关系   运营商除了优先级较低外。因此,一个      

在所有情况下,!= b产生与!(a == b)相同的结果。平等   如果操作数表达式没有边,则运算符是可交换的   的效果。

     

15.21.1数值等式算子==和!=

     

如果等于运算符的操作数都是数字类型,或者   一个是数字类型,另一个是可转换的(§5.1.8)   数字类型,对操作数执行二进制数字提升   (§5.6.2)。如果提升类型的操作数是int或long,那么a   执行整数相等测试;如果提升类型是浮点数或   double,然后执行浮点相等测试。注意   二进制数字促销执行值集转换(第5.1.13节)和   拆箱转换(第5.1.8节)。比较准确地进行   浮点值,无论什么值设置它们的代表   价值来自。

     

浮点相等测试按照以下方式执行   IEEE 754标准的规则:

     

如果任一操作数是NaN,则==的结果为false但是   !=的结果为真。实际上,当且仅当时,测试x!= x是真的   x的值是NaN。 (方法Float.isNaN和Double.isNaN也可以   用于测试值是否为NaN。)正零和负   零被认为是平等的。因此,例如,-0.0 == 0.0为真。   否则,两个不同的浮点值被认为是不相等的   由平等运营商。特别是,有一个价值   代表正无穷大,一个代表负数   无穷;每个比较仅与自身相等,并且每个都进行比较   不等于所有其他价值观。受这些考虑因素影响   浮点数,以下规则则保持整数   操作数或NaN以外的浮点操作数:值   如果左侧的值,则由==运算符生成的结果为true   操作数等于右操作数的值;除此以外,   结果是错误的。如果,则!=运算符生成的值为true   左侧操作数的值不等于   右手操作数;否则,结果是错误的。   15.21.2布尔等式运算符==和!=

     

如果等于运算符的操作数都是boolean类型,或者是   如果一个操作数是boolean类型而另一个是Boolean类型,   然后操作是布尔相等。布尔等式运算符   是联想的。如果其中一个操作数的类型为布尔值,则为   进行拆箱转换(第5.1.8节)。

     

如果操作数(在任何所需的拆箱之后),==的结果为真   转换)既是真的,也都是假的;否则,结果是   假的。

     

如果操作数都为true或两者都为false,则!=的结果为false;   否则,结果是真的。因此!=表现与^相同   (§15.22.2)应用于布尔操作数时。

     

15.21.3参考等式运算符==和!=

     

如果相等运算符的操作数都是引用   type或null类型,则操作是对象相等。一个   如果无法转换类型,则会发生编译时错误   通过转换转换将操作数转换为另一个的类型   (§5.5)。两个操作数的运行时值必然是   不相等的。

     

在运行时,如果操作数值都是,则==的结果为真   null或两者都指向同一个对象或数组;否则,结果   是假的。

     

如果操作数值都为null或两者都是,则!=的结果为false   引用相同的对象或数组;否则,结果是真的。

     

虽然==可用于比较String类型的引用,例如   等式测试确定两个操作数是否引用   相同的String对象。如果操作数是不同的,则结果为false   字符串对象,即使它们包含相同的字符序列。   可以通过对两个字符串s和t的内容进行相等性测试   方法调用s.equals(t)。另见§3.10.5。

答案 8 :(得分:0)

对象按值相等,但对象具有的值是对内存位置的引用。基元(即int,boolean,char,double)不使用引用,而是存储它们的值。因此,当使用==时,它会比较两者的值。在对象的情况下,它是一个参考;然而,在原语的情况下,它是它存储的价值。