为什么在下面的语句中得到false
。
int x = 10;
System.out.println("X="+x=="X="+x); //false
如果我是对的,那么经过评估,它将看起来像下面的陈述。。
System.out.println("X=10"=="X=10"); //true
为什么我会在这里得到true
。。
final int y = 10;
System.out.println("Y="+y=="Y="+y);
字符串应该使用equals
方法进行比较。==
比较身份。
"X=" + x == "X=" + x
创建了两个独立的字符串实例,虽然内容相等,但它们的标识不同。
"X=10" == "X=10"
是true
,因为字符串内部。编译器遇到两个内容相同的字符串文字,并决定这两个出现的字符串指向同一个string对象,因此它们具有相同的标识。
"Y=" + y == "Y=" + y
是true
,因为y
是常量表达式,编译器决定字符串和int可以在编译时连接,从而生成两个相等的字符串。实际上,就好像编写了"Y=10" == "Y=10"
。
让我们比较的所有方法
"X="+x=="X="+x
为false,因为这两个不同的实例和==
返回false(因为==
比较对象或字符串的地址(
为什么
这些不是字符串常量,我们将在下面关于常量的部分中看到
- "X=10〃=="X=10〃;为true,因为它们是字符串常量,编译器使用字符串intern为相同的内容字符串创建唯一对象
此外,字符串文字总是引用类string的同一实例。这是因为字符串文字——或者更一般地说,是常量表达式(§15.28(的值的字符串——是";被拘留";以便使用String.intern 方法共享唯一实例
- "Y="+y=";Y="+y是真的,因为它是常数表达式,这是因为变量
y
被声明为最终4.12.4。final Variables和String类型的编译时间常数表达式总是";被拘留">
基元类型或String类型的变量,即最终变量,并使用编译时常量表达式(§15.28(初始化,称为常量变量。
15.28.常量表达式
编译时常数表达式是表示基元类型的值或字符串的表达式,它不会突然完成,并且仅使用以下内容组成:
类型为String的编译时间常数表达式总是";被拘留";以便使用String.intern.方法共享唯一实例
常量表达式的示例:这与您的表达式"Y="+y
相似
"The integer " + Long.MAX_VALUE + " is mighty big."
如果可能的话,一个连接的字符串正在编译中,放在一起成为一个奇异的字符串,所以"X=" + "10"
变成"X=10"
,如果int
是final
,这也适用,但如果它是一个正常变量,那么这个过程当然不会发生。
然后,==被简化为比较中临时对象之间的对象比较工具,并因此而失败。
此外,请永远不要写这样的代码,因为你可以看到它很快就会导致问题,在适当的地方使用大括号和.equals((函数。
要详细说明死池,请回答最有可能在后台发生的事情是代码优化。
只有当String s1 == String s2
是同一个对象时,Java才会将其求值为true。因为y
被声明为final
,所以编译器可以用值替换y
的所有实例它被赋予
所以
final int y = 10;
System.out.println("Y="+y=="Y="+y);
成为
System.out.println("Y="+10=="Y="+10);
成为
String tmp = "Y="+10;
System.out.println(tmp==tmp);
成为
System.out.println(true);
但是,如果您没有将变量声明为final,那么编译器就无法执行此操作,因为它无法预测y在"Y="+y
和"Y="+y
之间会发生什么。
也做一些类似的事情
final int y = x;
System.out.println("Y="+y=="Y="+y);
将导致(我的(编译器跳过此优化,然后它的计算结果为false。
TL;博士
如果它是同一个对象,则它的计算结果为true
,在某些条件下,编译器将通过进行预计算来优化比较。