当我写下面的代码时,我遇到了一个问题
String hello = "Hello";
String str5 = "Hel" + "lo";
String str8 = "Hel";
String str9 = "lo";
String str10 = str8 + str9;
System.out.println("str10==hello?" + (str10 == hello));
System.out.println("str5==hello?" + (str5 == hello));
System.out.println("str10==str5?" + (str10 == str5));
然后我运行我的代码,控制台打印这个
str10 == hello ? false
str5 == hello ? true
str10 == str5 ? false
这让我很困惑。为什么第二次打印是真的,而第一次打印是假的??在我对String文字池的理解中,当定义一个字符串时,JVM将检查池中是否包含该字符串,如果不包含,则将该字符串放入池中。
在我的代码中,变量Hello存在于字符串池中,“Helo”和“lo”也在池中,我的问题是
我的jdk版本:1.6。0_29
我的IDE:Intellij Idea 11.2
有人能指出吗?非常感谢你
该准则有以下几点需要考虑:
String hello = "Hello";
这里“Hello”是一个分配给reference Hello的文本,因此该文本有自己的hashcode
String str5 = "Hel" + "lo";
这里的“Hel”“lo”是两个字面值的组合,并分配给reference hello,因此新字面值与第一个字面值相同,因此哈希代码相同
String str8 = "Hel";
String str9 = "lo";
这里str8和str9是两个引用,它们组合并指向一个新的引用hello,因此新的文本有自己的hashcode
String str10 = str8 + str9;
System.out.println("str10==hello?" + (str10 == hello));
System.out.println("str5==hello?" + (str5 == hello));
System.out.println("str10==str5?" + (str10 == str5));
当您使用==时,它通过哈希代码和值匹配。因此,不匹配。
尝试使用
字符串_1。等于(字符串_2)
而不是
字符串_1==字符串_2
你将只得到价值匹配。因此都是真的
请参考以下答案(Java中==vs equals()之间的区别是什么?):
equals()方法比较字符串实例(堆上)内的“值”,而不管两(2)个对象引用是否引用同一个字符串实例。如果任何两(2)个String类型的对象引用引用同一个String实例,那就太好了!如果两(2)个对象引用引用了两(2)个不同的字符串实例。。这没什么区别。它是被比较的每个字符串实例中的“值”(即:字符数组的内容)。
另一方面,“==”操作符比较两个对象引用的值,以查看它们是否引用同一个字符串实例。如果两个对象引用的值“引用”同一个字符串实例,则布尔表达式的结果将为“true”。。嗯。另一方面,如果两个对象引用的值“引用”不同的字符串实例(即使两个字符串实例具有相同的“值”,即每个字符串实例的字符数组的内容相同),则布尔表达式的结果将为“false”。
String hello = "Hello"; // at compile time string is known so in String Constant Pool
String str5 = "Hel" + "lo"; // at compile time string is known so in String Constant Pool same object as in variable hello
String str8 = "Hel"; // at compile time string is known so in String Constant Pool
String str9 = "lo"; // at compile time string is known so in String Constant Pool
String str10 = str8 + str9; // at runtime don't know values of str8 and str9 so in String Constant Pool new object different from variable hello
str10 == hello ? false // as str10 has new object and not the same as in hello
str5 == hello ? true // both were created at compile time so compiler know what's the result in str5 and referenced the same object to str5 as in hello
str10 == str5 ? false // str10 is a different object, hello and str5 are referenced same object as created at compile time.
它的行为应该是正常的。JLS中有两个章节对此进行了论述。
JLS#3.10。5:
作为常量表达式(§15.28)值的字符串被“驻留”,以便使用S方法共享唯一的实例tring.intern.
JLS#15.28列出了常量表达式。特别是,字符串文字是常量表达式(“Hel”和“lo”),但要将变量视为常量,它需要是最终的。
在您的情况下,如果您稍微更改代码以使str8
和str9
保持不变,您将得到true
三次:
final String str8 = "Hel";
final String str9 = "lo";
问题内容: 这与Java字符串常量池有关。在我的一个程序中,我正在解密数据库的密码并将其存储在字符串中。我听说Java字符串将存储在Constant池中,并且不会被VM重新启动或加载了String Quits的ClassLoader破坏。 如果是这种情况,我的密码将存储在字符串池中。我非常关心这个问题。还有其他方法可以销毁这些文字或我可以做的其他任何事情。 请对此提出建议, 问候,阳光明媚。 问题
问题内容: 为什么在这些情况下输出不同? ==> 印刷:2010年 ==> 打印:200 为什么第一个输出不是30?它与运算符优先级有关吗?就像首先将“ printing”和x连接在一起,然后将结果字符串和y连接在一起?我对么? 问题答案: 它的规则 我在下面显示从高到低的优先顺序: **如果运算符具有相同的优先级 ,* 则 此方法起作用 * 现在 :是字符串” :是Java中唯一将Number连
当使用关键字 new 创建字符串时,它使用采用 String 文本的构造函数创建新的 String 对象。我想知道在调用 String 构造函数之前,文本是否存储在常量池中。 我这么问的原因是,在《OCA Java SE 7程序员I认证指南》中,Mala Gupta写道: 她在第一行表示,new创建的String对象不会存储在常量池中。这很好,但不清楚的是,第一行构造函数中的字面“Summer”是
我的问题很简单。有什么区别-
问题内容: 问题1 在第一种情况下,我知道这是两个字符串文字的串联,因此将对结果“ I Love Java”进行检查,使结果为true。但是,我不确定第二种情况。 问题2 上面的返回false,但是如果我注释掉第1行和第2行,则返回true。这是为什么? 问题答案: 问题的第一部分很简单:Java编译器将多个字符串文字的串联视为一个字符串文字,即 和 是两个完全相同的字符串文字,可以正确地进行in
问题内容: 这是以前有关Java中的String初始化的一些问题的后续问题。 在用Java进行了一些小测试之后,我面临以下问题: 为什么我可以执行此语句 当str2一个String对象初始化为,但我不能调用方法toString()上str2?那么Java如何将空字符串对象和字符串文字串联起来? 顺便说一句,我还尝试将一个初始化为null和字符串文字的Integer连接起来,”a_literal_s