简体   繁体   English

关于Java String文字池和String的串联的混淆

[英]a confusion about java String literal pool and String's concatenation

all, i faced a problem when a write the code below 所有,当我写下面的代码时,我遇到了一个问题

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));

then i run my code and the console print this 然后我运行我的代码,控制台将其打印出来

str10 == hello ? false
str5 == hello ? true
str10 == str5 ? false

this confused me a lot. 这让我很困惑。 why the second print TRUE but the first print FALSE?? 为什么第二个打印为TRUE但第一个打印为FALSE? in my comprehension of String literal pool,when a string defined and JVM will check if the pool contains that string,if not ,put the string into the pool. 在我理解String文字池时,当定义了一个字符串时,JVM将检查该池是否包含该字符串,如果不包含该字符串,则将该字符串放入池中。
in my code,variable hello exists in string pool," Helo " and " lo " also in the pool,my question is 在我的代码中,字符串池中存在变量hello ,池中也存在“ Helo ”和“ lo ”,我的问题是

  1. if the result of the concatenation of " Helo " and " lo " exists in the pool. 如果池中存在“ Helo ”和“ lo ”的并置结果。
  2. what's the difference between the definition about str5 and str10s',and why they are not "=="? 关于str5和str10s的定义之间有什么区别,为什么它们不是“ ==”? does str5 and str10 refer to the diffrent " Hello ” that in the string pool?("==" seems to mean the reference is the same object) str5和str10是否引用字符串池中不同的“ Hello ”?(“ ==”似乎表示引用是同一对象)

my jdk version :1.6.0_29 我的jdk版本:1.6.0_29
my IDE:Intellij Idea 11.2 我的IDE:Intellij Idea 11.2

anyone can point it out? 有人可以指出吗? thank you very much 非常感谢你

It behaves as it should. 它的行为应有。 It is adressed in two sections of the JLS. JLS分为两个部分。

JLS #3.10.5 : JLS#3.10.5

strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern. 使用String.intern方法,对作为常量表达式(第15.28节)的值的字符串进行“ interned”,以便共享唯一的实例。

JLS #15.28 lists what is considered as a constant expression. JLS#15.28列出了被视为常量表达式的内容。 In particular, string literals are constant expressions ("Hel" and "lo") but for a variable to be considered a constant, it needs to be final. 特别是,字符串文字是常量表达式(“ Hel”和“ lo”),但是要使变量被认为是常量,则必须为最终变量。

In your case, if you change your code slightly to make str8 and str9 constant, you will get true three times: 在你的情况,如果你改变你的代码稍微做str8str9不变,你会得到true三次:

final String str8 = "Hel";
final String str9 = "lo";
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.

The code has the following points to consider: 该代码需要考虑以下几点:

String hello = "Hello";

Here "Hello" is a literal assigned to reference hello thus the literal has its own hashcode 这里“ Hello”是分配给引用hello的文字,因此该文字具有自己的哈希码

String str5 = "Hel" + "lo";

Here "Hel"+"lo" are 2 literals combined and assigned to reference hello thus the new literal is same as the first one and thus same hashcode 这里“ Hel” +“ lo”是2个文字,它们组合并分配给引用hello,因此新文字与第一个文字相同,因此哈希码也相同

String str8 = "Hel";
String str9 = "lo";

Here str8 + str9 are 2 references which combine and point to a new reference hello thus the new literal has its own hashcode 这里str8 + str9是2个引用,它们组合并指向一个新引用hello,因此新文字具有其自己的哈希码

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));

when you use == it matches by hash code and value. 当使用==时,它通过哈希码和值匹配。 thus the mismatch. 因此不匹配。

try to use 尝试使用

string_1.equals(string_2) string_1.equals(string_2)

instead of 代替

string_1 ==string_2 字符串_1 ==字符串_2

and you will get value matching only. 您将只获得价值匹配。 thus all true 因此,一切都是真的

Please refer the below answer also(from What is the difference between == vs equals() in Java? ): 请也参考下面的答案(从Java中== vs equals()之间有什么区别? ):

The equals() method compares the "value" inside String instances (on the heap) irrespective if the two(2) object references refer to the same String instance or not. equals()方法比较String实例内部(在堆上)的“值”,而不管two(2)对象引用是否引用相同的String实例。 If any two(2) object references of type String refer to the same String instance then great! 如果String类型的任何两个(2)对象引用都引用相同的String实例,那就太好了! If the two(2) object references refer to two(2) different String instances .. it doesn't make a difference. 如果two(2)对象引用引用了two(2)个不同的String实例..则没有任何区别。 Its the "value" (that is: the contents of the character array) inside each String instance that is being compared. 它是被比较的每个String实例内部的“值”(即:字符数组的内容)。

On the other hand, the "==" operator compares the value of two object references to see whether they refer to the same String instance. 另一方面,“ ==”运算符比较两个对象引用的值,以查看它们是否引用相同的String实例。 If the value of both object references "refer to" the same String instance then the result of the boolean expression would be "true"..duh. 如果两个对象的值引用“引用”相同的String实例,则布尔表达式的结果将为“ true” .. duh。 If, on the other hand, the value of both object references "refer to" different String instances (even though both String instances have identical "values", that is, the contents of the character arrays of each String instance are the same) the result of the boolean expression would be "false". 另一方面,如果两个对象引用的值“引用”不同的String实例(即使两个String实例都具有相同的“值”,即每个String实例的字符数组的内容相同),则布尔表达式的结果将为“ false”。

If u compare two strings use string.equals not string1 == string2 如果u比较两个字符串,请使用string.equals而不是string1 == string2

try it: 试试吧:

System.out.println("str10==hello?" + (str10.equals(hello));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM