Java 为什么字符串池对文本和变量的行为不同?

Java 为什么字符串池对文本和变量的行为不同?,java,string,Java,String,当我用(++)运算符用双引号表示2字符串时,并将其与具有相同值的其他字符串文本进行比较,结果为true。。但是当我计算2个字符串变量并比较时,会给出false吗?为什么会发生这种情况 据我所知,当我们使用(+)运算符连接字符串时,JVM返回newStringBuilder(string…).toString(),它在堆内存中创建一个新字符串实例,在字符串池中创建一个引用。如果这是真的,它如何在一个场景中返回true,在另一个场景中返回false 第一个场景: String string1

当我用
(++
)运算符用双引号表示2字符串时,并将其与具有相同值的其他字符串文本进行比较,结果为true。。但是当我计算2个字符串变量并比较时,会给出false吗?为什么会发生这种情况


据我所知,当我们使用(+)运算符连接字符串时,JVM返回new
StringBuilder(string…).toString()
,它在堆内存中创建一个新字符串实例,在字符串池中创建一个引用。如果这是真的,它如何在一个场景中返回true,在另一个场景中返回false

第一个场景:

    String string1 = "wel";
    String string2 = "come";
    string1 = string1 + string2; //welcome

    String string3 = "welcome";
    System.out.println(string3 == string1); // this returns false but have same hashcode
    String string4 = "wel" + "come";
    String string5 = "wel" + "come";
    System.out.println(string4 == string5); // this returns true
第二种情况:

    String string1 = "wel";
    String string2 = "come";
    string1 = string1 + string2; //welcome

    String string3 = "welcome";
    System.out.println(string3 == string1); // this returns false but have same hashcode
    String string4 = "wel" + "come";
    String string5 = "wel" + "come";
    System.out.println(string4 == string5); // this returns true

有人能帮我吗?

请关注评论

 string1 = string1 + string2; //StringBuilder(string...).toString() which creates a new instance in heap..

 String string3 = "welcome"; // It is not in heap. 
所以
string3==string1
false

  String string4 = "wel" + "come"; //Evaluated at compile time

  String string5 = "wel" + "come"; //Evaluated at compile time and reffering to previous literal
所以
string4==string5
true


据我所知,当我们使用(+)运算符连接字符串时,JVM返回新的StringBuilder(string…).toString(),它在堆内存中创建一个新的字符串实例

正确,除非两个操作数都是文本,在这种情况下,在编译时创建一个字符串常量并合并

和字符串池中的一个引用

错。字符串池中只有字符串常量和
String.intern()
返回值

如果这是真的

事实并非如此

它是如何在一个场景中返回true而在另一个场景中返回false的


因为premiss不正确。

如果您使用非
最终
字符串
变量,是的,您将拥有
StringBuilder
。如果使用
String
literals,即常量,则不会使用
equals()
方法将字符串作为
string3.equals(string1)进行比较
如果在源代码中串联字符串文本,例如,
“wel”+“come”
,则“据我所知,当我们使用(+)运算符连接字符串时,JVM返回新的StringBuilder(字符串…)。toString()在堆内存中创建新的字符串实例”的可能重复项不是真的。这种连接是在编译时完成的,就像您编写了
“welcome”
一样。@user251414中指出了这一点:我在这里使用==检查两个值是否引用字符串池中的同一实例,这是验证字符串池引用的唯一方法。目的是了解字符串池的工作原理。“在编译时创建一个文本”-这在挑剔的级别上是不准确的。文字是实际的语法特征,如源代码中的
123
“abc”
。在编译时,将在常量池中创建一个条目-编译器不会生成源代码,因此不会创建文本。(我也不会说常数是被创建的,因为它是变量的质量,而不是值的质量,值是不可变的——所有字符串值都是不可变的,不管它们是否为文本。)@millimoose我同意“字符串文本”的说法,在你发表评论前几分钟,我已经解决了这个问题。我不同意“常数”这个说法。这就是为什么它被称为“常量池”。对于常数。有许多常数不是变量。首先,字符串文本:-我承认父类中的部分在语义问题上存在分歧,我只是补充了这一点来完成我的思考,而不是指出错误。