String comparison confused

后端 未结 3 507
执笔经年
执笔经年 2021-01-22 16:24

Before we move on: I understand we should use .equals() to compare content. I am now just talking about if the actual references are the same for the following scenario.

相关标签:
3条回答
  • 2021-01-22 16:56

    The comparison works as follows:

    String str1 = "str";`   //"str" is created in SCP and str1 is a reference to that    
    String str2 = "string";` //"string" is created in SCP and str2 is a reference   
    String str3 = "ing";`  //"ing" is created in SCP and str3 is a reference    
    String str4 = str1 + str3;//"string" will be created on Heap and str4 is a reference (this is because if any string created at runntime will always be created on Heap) (here SCP already has this "string" so no change) make a note      that str4 is pointing to Heap string Object and not SCP   
    
    str1 = str4; `// str1 and str4 will start pointing to same String Object on Heap    
    String str5 = "string";`  // SCP already has this and str2 pointing to that so now onwards str5 will also point to it   
    
    based on above    
    1. str1 and str4 -- > are pointing to "string" object on heap    
    2. str2 and str5 -- > are pointing to "string" object in scp  
    3. str3 -- > is pointing to "ing" in scp   
    
    and finally the corresponding output can be traced based on above lines:
    
    System.out.println(str1==str2);`//false   
    System.out.println(str1.intern()==str2.intern());`//true   
    System.out.println(str1==str5);`//false   
    System.out.println(str2==str5);`//true   
    System.out.println("str"+"ing"=="string");`//true as "str"+"ing" will be replaced by "string" at compile time only (constant)
    
    0 讨论(0)
  • 2021-01-22 16:59

    Only string literals and constant expressions are guaranteed to be pooled. Since str1 + str2 is not a literal, it's up to the JVM whether or not the result will be interned. You can force it via calling intern() as you have already found out.

    This is defined in § 3.10.5 of the Java Language Specification:

    A string literal is a reference to an instance of class String (§4.3.1, §4.3.3).

    Moreover, a string literal always refers to the same instance of class String. This is because string literals – or, more generally, strings that are the values of constant expressions (§15.28) – are “interned” so as to share unique instances, using the method String.intern.

    Your second example, "str" + "ing", is a constant expression so it is guaranteed to be interned.

    Also see the JavaDoc for String.intern.

    This is an attempt to explain what is going on. Well-written code should probably never rely on this but always use the equals method. Any reasonable JRE will have a check like

    if (this == other)
      return true;
    

    very close to the top of String.equals so performance wise, it shouldn't matter.

    0 讨论(0)
  • 2021-01-22 17:06

    Always use equals method for comparing strings. The trouble about interning is that each version of JDK does it a bit differently, so I wouldn't have counted on that unless you want to call intern every time on the string.

    0 讨论(0)
提交回复
热议问题