If String is immutable, if String constant pool having only one copy of a particular value how the following...












4
















This question already has an answer here:




  • concatenation of string constants in java [duplicate]

    2 answers




String s1 = "A"+"B";
String s2 = "AB";
System.out.println(s1 == s2); // true


String s1 and s2 should refer to String value "AB" in String constant pool. So one value "AB" one reference, reference comparison giving is true. (this is acceptable according to the theory I am aware of)



String st1 = "C D";
st1 += " E";
String str2 = "C D E";
System.out.println(st1 == str2); // false


String str1 and str2 both should refer to String "C D E" in String constant pool (two identical values cannot be in String pool ). Then why the reference comparison of str1 and str2 return false?



What I am missing here?



Thanks










share|improve this question















marked as duplicate by GhostCat java
Users with the  java badge can single-handedly close java questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 14 '18 at 11:48


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.



















  • @AlexSalauyou st1 += " E". so st1, shouldn't it hold the reference to "C D E" in string constant pool?

    – shanika yrs
    Nov 14 '18 at 11:05













  • @AlexSalauyou pretty sure st1 += " E" is just the short form of st1 = st1 + " E" and both will produce the same bytecode and in fact change/reassign st1

    – OH GOD SPIDERS
    Nov 14 '18 at 11:06











  • @OHGODSPIDERS shame on me ) thanks

    – Alex Salauyou
    Nov 14 '18 at 11:07






  • 6





    The reason is that in first case "A" + "B" is evaluated to constant "AB" in compile time, thus result is taken from the pool on instance initialization. In second case, you perform operation in code flow. There is no guarantee that equivalent Strings are same object until you adjust them calling String#intern

    – Alex Salauyou
    Nov 14 '18 at 11:08








  • 1





    docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5

    – Alex Salauyou
    Nov 14 '18 at 11:12


















4
















This question already has an answer here:




  • concatenation of string constants in java [duplicate]

    2 answers




String s1 = "A"+"B";
String s2 = "AB";
System.out.println(s1 == s2); // true


String s1 and s2 should refer to String value "AB" in String constant pool. So one value "AB" one reference, reference comparison giving is true. (this is acceptable according to the theory I am aware of)



String st1 = "C D";
st1 += " E";
String str2 = "C D E";
System.out.println(st1 == str2); // false


String str1 and str2 both should refer to String "C D E" in String constant pool (two identical values cannot be in String pool ). Then why the reference comparison of str1 and str2 return false?



What I am missing here?



Thanks










share|improve this question















marked as duplicate by GhostCat java
Users with the  java badge can single-handedly close java questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 14 '18 at 11:48


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.



















  • @AlexSalauyou st1 += " E". so st1, shouldn't it hold the reference to "C D E" in string constant pool?

    – shanika yrs
    Nov 14 '18 at 11:05













  • @AlexSalauyou pretty sure st1 += " E" is just the short form of st1 = st1 + " E" and both will produce the same bytecode and in fact change/reassign st1

    – OH GOD SPIDERS
    Nov 14 '18 at 11:06











  • @OHGODSPIDERS shame on me ) thanks

    – Alex Salauyou
    Nov 14 '18 at 11:07






  • 6





    The reason is that in first case "A" + "B" is evaluated to constant "AB" in compile time, thus result is taken from the pool on instance initialization. In second case, you perform operation in code flow. There is no guarantee that equivalent Strings are same object until you adjust them calling String#intern

    – Alex Salauyou
    Nov 14 '18 at 11:08








  • 1





    docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5

    – Alex Salauyou
    Nov 14 '18 at 11:12
















4












4








4


1







This question already has an answer here:




  • concatenation of string constants in java [duplicate]

    2 answers




String s1 = "A"+"B";
String s2 = "AB";
System.out.println(s1 == s2); // true


String s1 and s2 should refer to String value "AB" in String constant pool. So one value "AB" one reference, reference comparison giving is true. (this is acceptable according to the theory I am aware of)



String st1 = "C D";
st1 += " E";
String str2 = "C D E";
System.out.println(st1 == str2); // false


String str1 and str2 both should refer to String "C D E" in String constant pool (two identical values cannot be in String pool ). Then why the reference comparison of str1 and str2 return false?



What I am missing here?



Thanks










share|improve this question

















This question already has an answer here:




  • concatenation of string constants in java [duplicate]

    2 answers




String s1 = "A"+"B";
String s2 = "AB";
System.out.println(s1 == s2); // true


String s1 and s2 should refer to String value "AB" in String constant pool. So one value "AB" one reference, reference comparison giving is true. (this is acceptable according to the theory I am aware of)



String st1 = "C D";
st1 += " E";
String str2 = "C D E";
System.out.println(st1 == str2); // false


String str1 and str2 both should refer to String "C D E" in String constant pool (two identical values cannot be in String pool ). Then why the reference comparison of str1 and str2 return false?



What I am missing here?



Thanks





This question already has an answer here:




  • concatenation of string constants in java [duplicate]

    2 answers








java string






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 11:30









Morteza Jalambadani

7361921




7361921










asked Nov 14 '18 at 11:01









shanika yrsshanika yrs

939




939




marked as duplicate by GhostCat java
Users with the  java badge can single-handedly close java questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 14 '18 at 11:48


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.









marked as duplicate by GhostCat java
Users with the  java badge can single-handedly close java questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 14 '18 at 11:48


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.















  • @AlexSalauyou st1 += " E". so st1, shouldn't it hold the reference to "C D E" in string constant pool?

    – shanika yrs
    Nov 14 '18 at 11:05













  • @AlexSalauyou pretty sure st1 += " E" is just the short form of st1 = st1 + " E" and both will produce the same bytecode and in fact change/reassign st1

    – OH GOD SPIDERS
    Nov 14 '18 at 11:06











  • @OHGODSPIDERS shame on me ) thanks

    – Alex Salauyou
    Nov 14 '18 at 11:07






  • 6





    The reason is that in first case "A" + "B" is evaluated to constant "AB" in compile time, thus result is taken from the pool on instance initialization. In second case, you perform operation in code flow. There is no guarantee that equivalent Strings are same object until you adjust them calling String#intern

    – Alex Salauyou
    Nov 14 '18 at 11:08








  • 1





    docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5

    – Alex Salauyou
    Nov 14 '18 at 11:12





















  • @AlexSalauyou st1 += " E". so st1, shouldn't it hold the reference to "C D E" in string constant pool?

    – shanika yrs
    Nov 14 '18 at 11:05













  • @AlexSalauyou pretty sure st1 += " E" is just the short form of st1 = st1 + " E" and both will produce the same bytecode and in fact change/reassign st1

    – OH GOD SPIDERS
    Nov 14 '18 at 11:06











  • @OHGODSPIDERS shame on me ) thanks

    – Alex Salauyou
    Nov 14 '18 at 11:07






  • 6





    The reason is that in first case "A" + "B" is evaluated to constant "AB" in compile time, thus result is taken from the pool on instance initialization. In second case, you perform operation in code flow. There is no guarantee that equivalent Strings are same object until you adjust them calling String#intern

    – Alex Salauyou
    Nov 14 '18 at 11:08








  • 1





    docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5

    – Alex Salauyou
    Nov 14 '18 at 11:12



















@AlexSalauyou st1 += " E". so st1, shouldn't it hold the reference to "C D E" in string constant pool?

– shanika yrs
Nov 14 '18 at 11:05







@AlexSalauyou st1 += " E". so st1, shouldn't it hold the reference to "C D E" in string constant pool?

– shanika yrs
Nov 14 '18 at 11:05















@AlexSalauyou pretty sure st1 += " E" is just the short form of st1 = st1 + " E" and both will produce the same bytecode and in fact change/reassign st1

– OH GOD SPIDERS
Nov 14 '18 at 11:06





@AlexSalauyou pretty sure st1 += " E" is just the short form of st1 = st1 + " E" and both will produce the same bytecode and in fact change/reassign st1

– OH GOD SPIDERS
Nov 14 '18 at 11:06













@OHGODSPIDERS shame on me ) thanks

– Alex Salauyou
Nov 14 '18 at 11:07





@OHGODSPIDERS shame on me ) thanks

– Alex Salauyou
Nov 14 '18 at 11:07




6




6





The reason is that in first case "A" + "B" is evaluated to constant "AB" in compile time, thus result is taken from the pool on instance initialization. In second case, you perform operation in code flow. There is no guarantee that equivalent Strings are same object until you adjust them calling String#intern

– Alex Salauyou
Nov 14 '18 at 11:08







The reason is that in first case "A" + "B" is evaluated to constant "AB" in compile time, thus result is taken from the pool on instance initialization. In second case, you perform operation in code flow. There is no guarantee that equivalent Strings are same object until you adjust them calling String#intern

– Alex Salauyou
Nov 14 '18 at 11:08






1




1





docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5

– Alex Salauyou
Nov 14 '18 at 11:12







docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5

– Alex Salauyou
Nov 14 '18 at 11:12














4 Answers
4






active

oldest

votes


















3














The answer is very simple.



When you type String st1 += " E" or String st1 = st1 + " E" JVM transforms it to the StringBuilder syntax like String st1 = new StringBuilder(st1).append(" E").toString().
When you look at StringBuilder.toString():



@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}


... you see new String(), it creates new string not using constants from String Pool.



Finally, if you replace st1 += " E" to s1 = (s1 + " E").intern(), you get true as results.



P.S.



If I remember correctly, this is valid from JVM 6 or so. That's why now you can use string concatenation str = str1 + str2 (internally this is str = new StringBuilder(str1).append(str2).toString()). But it is not true, when you use it inside loop:



String str = "A";

for(int i = 1; i <= 3; i++)
str += i;


JVM cannot optimize it to use StringBuilder and does old-style concatenation with generating multiple temporary strings, which is very slowly.






share|improve this answer

































    1














    In addition to Alex Salauyou and oleg.cherednik answers:
    In bytecode below you can see, that string s1 was evaluated on compile time as Alex Salauyou told, but the second string was constructed with StringBuilder as oleg.cherednik explained.




    Code:
    0: ldc #2 // String AB <- s1 evaluated on compile time there
    2: astore_1
    3: ldc #2 // String AB
    5: astore_2
    6: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
    9: aload_1
    10: aload_2
    11: if_acmpne 18
    14: iconst_1
    15: goto 19
    18: iconst_0
    19: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
    22: ldc #5 // String C D
    24: astore_3
    25: new #6 // class java/lang/StringBuilder
    28: dup
    29: invokespecial #7 // Method java/lang/StringBuilder."<init>":()V
    32: aload_3
    33: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    36: ldc #9 // String E
    38: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    41: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
    44: astore_3
    45: ldc #11 // String C D E
    47: astore 4
    49: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
    52: aload_3
    53: aload 4
    55: if_acmpne 62
    58: iconst_1
    59: goto 63
    62: iconst_0
    63: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
    66: return






    share|improve this answer































      1














      The rule you mentioned regards string literals, i.e. pieces of code written in double quotes, like "AB". Result of operation, which may be evaluated on compile time ("constant expression"), is immediately replaced by resulting literal:



      String st1 = "A" + "B";


      is the same as writing:



      String st1 = "AB";


      And equal literals are always evaluated to same String object, as told in specification (https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5)




      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"




      In your question, you assume that constant pool cannot hold two different instances of the same value, that is right, but that does not imply that every String instance resides in constant pool. In fact, there is no possibility to guaranteely make equal strings created on runtime be the same object, for example:



      String st1 = "AB";
      String st2 = new String(st1);
      String st3 = new String(st1);


      will result in three different String instances: first as literal evaluation result, taken from constant pool, others as newly constructed objects (though new always creates a new object!). == on them will fail unless you adjust them using String#intern:



      st1 == st2.intern();  // true





      share|improve this answer

































        0














        st1 + " E" 


        this line of code will reassign



        String st1 = "C D";
        st1 += " E";
        String str2 = "C D E";
        System.out.println(st1.hashCode() == str2.hashCode()); //True


        fetch the internal address that same
        thank u






        share|improve this answer
























        • String#hashCode is calculated upon its value, not "internal address"

          – Alex Salauyou
          Nov 14 '18 at 12:18




















        4 Answers
        4






        active

        oldest

        votes








        4 Answers
        4






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        3














        The answer is very simple.



        When you type String st1 += " E" or String st1 = st1 + " E" JVM transforms it to the StringBuilder syntax like String st1 = new StringBuilder(st1).append(" E").toString().
        When you look at StringBuilder.toString():



        @Override
        public String toString() {
        // Create a copy, don't share the array
        return new String(value, 0, count);
        }


        ... you see new String(), it creates new string not using constants from String Pool.



        Finally, if you replace st1 += " E" to s1 = (s1 + " E").intern(), you get true as results.



        P.S.



        If I remember correctly, this is valid from JVM 6 or so. That's why now you can use string concatenation str = str1 + str2 (internally this is str = new StringBuilder(str1).append(str2).toString()). But it is not true, when you use it inside loop:



        String str = "A";

        for(int i = 1; i <= 3; i++)
        str += i;


        JVM cannot optimize it to use StringBuilder and does old-style concatenation with generating multiple temporary strings, which is very slowly.






        share|improve this answer






























          3














          The answer is very simple.



          When you type String st1 += " E" or String st1 = st1 + " E" JVM transforms it to the StringBuilder syntax like String st1 = new StringBuilder(st1).append(" E").toString().
          When you look at StringBuilder.toString():



          @Override
          public String toString() {
          // Create a copy, don't share the array
          return new String(value, 0, count);
          }


          ... you see new String(), it creates new string not using constants from String Pool.



          Finally, if you replace st1 += " E" to s1 = (s1 + " E").intern(), you get true as results.



          P.S.



          If I remember correctly, this is valid from JVM 6 or so. That's why now you can use string concatenation str = str1 + str2 (internally this is str = new StringBuilder(str1).append(str2).toString()). But it is not true, when you use it inside loop:



          String str = "A";

          for(int i = 1; i <= 3; i++)
          str += i;


          JVM cannot optimize it to use StringBuilder and does old-style concatenation with generating multiple temporary strings, which is very slowly.






          share|improve this answer




























            3












            3








            3







            The answer is very simple.



            When you type String st1 += " E" or String st1 = st1 + " E" JVM transforms it to the StringBuilder syntax like String st1 = new StringBuilder(st1).append(" E").toString().
            When you look at StringBuilder.toString():



            @Override
            public String toString() {
            // Create a copy, don't share the array
            return new String(value, 0, count);
            }


            ... you see new String(), it creates new string not using constants from String Pool.



            Finally, if you replace st1 += " E" to s1 = (s1 + " E").intern(), you get true as results.



            P.S.



            If I remember correctly, this is valid from JVM 6 or so. That's why now you can use string concatenation str = str1 + str2 (internally this is str = new StringBuilder(str1).append(str2).toString()). But it is not true, when you use it inside loop:



            String str = "A";

            for(int i = 1; i <= 3; i++)
            str += i;


            JVM cannot optimize it to use StringBuilder and does old-style concatenation with generating multiple temporary strings, which is very slowly.






            share|improve this answer















            The answer is very simple.



            When you type String st1 += " E" or String st1 = st1 + " E" JVM transforms it to the StringBuilder syntax like String st1 = new StringBuilder(st1).append(" E").toString().
            When you look at StringBuilder.toString():



            @Override
            public String toString() {
            // Create a copy, don't share the array
            return new String(value, 0, count);
            }


            ... you see new String(), it creates new string not using constants from String Pool.



            Finally, if you replace st1 += " E" to s1 = (s1 + " E").intern(), you get true as results.



            P.S.



            If I remember correctly, this is valid from JVM 6 or so. That's why now you can use string concatenation str = str1 + str2 (internally this is str = new StringBuilder(str1).append(str2).toString()). But it is not true, when you use it inside loop:



            String str = "A";

            for(int i = 1; i <= 3; i++)
            str += i;


            JVM cannot optimize it to use StringBuilder and does old-style concatenation with generating multiple temporary strings, which is very slowly.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 14 '18 at 11:39

























            answered Nov 14 '18 at 11:21









            oleg.cherednikoleg.cherednik

            6,60221118




            6,60221118

























                1














                In addition to Alex Salauyou and oleg.cherednik answers:
                In bytecode below you can see, that string s1 was evaluated on compile time as Alex Salauyou told, but the second string was constructed with StringBuilder as oleg.cherednik explained.




                Code:
                0: ldc #2 // String AB <- s1 evaluated on compile time there
                2: astore_1
                3: ldc #2 // String AB
                5: astore_2
                6: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
                9: aload_1
                10: aload_2
                11: if_acmpne 18
                14: iconst_1
                15: goto 19
                18: iconst_0
                19: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
                22: ldc #5 // String C D
                24: astore_3
                25: new #6 // class java/lang/StringBuilder
                28: dup
                29: invokespecial #7 // Method java/lang/StringBuilder."<init>":()V
                32: aload_3
                33: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                36: ldc #9 // String E
                38: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                41: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
                44: astore_3
                45: ldc #11 // String C D E
                47: astore 4
                49: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
                52: aload_3
                53: aload 4
                55: if_acmpne 62
                58: iconst_1
                59: goto 63
                62: iconst_0
                63: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
                66: return






                share|improve this answer




























                  1














                  In addition to Alex Salauyou and oleg.cherednik answers:
                  In bytecode below you can see, that string s1 was evaluated on compile time as Alex Salauyou told, but the second string was constructed with StringBuilder as oleg.cherednik explained.




                  Code:
                  0: ldc #2 // String AB <- s1 evaluated on compile time there
                  2: astore_1
                  3: ldc #2 // String AB
                  5: astore_2
                  6: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
                  9: aload_1
                  10: aload_2
                  11: if_acmpne 18
                  14: iconst_1
                  15: goto 19
                  18: iconst_0
                  19: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
                  22: ldc #5 // String C D
                  24: astore_3
                  25: new #6 // class java/lang/StringBuilder
                  28: dup
                  29: invokespecial #7 // Method java/lang/StringBuilder."<init>":()V
                  32: aload_3
                  33: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                  36: ldc #9 // String E
                  38: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                  41: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
                  44: astore_3
                  45: ldc #11 // String C D E
                  47: astore 4
                  49: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
                  52: aload_3
                  53: aload 4
                  55: if_acmpne 62
                  58: iconst_1
                  59: goto 63
                  62: iconst_0
                  63: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
                  66: return






                  share|improve this answer


























                    1












                    1








                    1







                    In addition to Alex Salauyou and oleg.cherednik answers:
                    In bytecode below you can see, that string s1 was evaluated on compile time as Alex Salauyou told, but the second string was constructed with StringBuilder as oleg.cherednik explained.




                    Code:
                    0: ldc #2 // String AB <- s1 evaluated on compile time there
                    2: astore_1
                    3: ldc #2 // String AB
                    5: astore_2
                    6: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
                    9: aload_1
                    10: aload_2
                    11: if_acmpne 18
                    14: iconst_1
                    15: goto 19
                    18: iconst_0
                    19: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
                    22: ldc #5 // String C D
                    24: astore_3
                    25: new #6 // class java/lang/StringBuilder
                    28: dup
                    29: invokespecial #7 // Method java/lang/StringBuilder."<init>":()V
                    32: aload_3
                    33: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                    36: ldc #9 // String E
                    38: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                    41: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
                    44: astore_3
                    45: ldc #11 // String C D E
                    47: astore 4
                    49: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
                    52: aload_3
                    53: aload 4
                    55: if_acmpne 62
                    58: iconst_1
                    59: goto 63
                    62: iconst_0
                    63: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
                    66: return






                    share|improve this answer













                    In addition to Alex Salauyou and oleg.cherednik answers:
                    In bytecode below you can see, that string s1 was evaluated on compile time as Alex Salauyou told, but the second string was constructed with StringBuilder as oleg.cherednik explained.




                    Code:
                    0: ldc #2 // String AB <- s1 evaluated on compile time there
                    2: astore_1
                    3: ldc #2 // String AB
                    5: astore_2
                    6: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
                    9: aload_1
                    10: aload_2
                    11: if_acmpne 18
                    14: iconst_1
                    15: goto 19
                    18: iconst_0
                    19: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
                    22: ldc #5 // String C D
                    24: astore_3
                    25: new #6 // class java/lang/StringBuilder
                    28: dup
                    29: invokespecial #7 // Method java/lang/StringBuilder."<init>":()V
                    32: aload_3
                    33: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                    36: ldc #9 // String E
                    38: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                    41: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
                    44: astore_3
                    45: ldc #11 // String C D E
                    47: astore 4
                    49: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
                    52: aload_3
                    53: aload 4
                    55: if_acmpne 62
                    58: iconst_1
                    59: goto 63
                    62: iconst_0
                    63: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
                    66: return







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 14 '18 at 11:42









                    Aleksandr SemyannikovAleksandr Semyannikov

                    591216




                    591216























                        1














                        The rule you mentioned regards string literals, i.e. pieces of code written in double quotes, like "AB". Result of operation, which may be evaluated on compile time ("constant expression"), is immediately replaced by resulting literal:



                        String st1 = "A" + "B";


                        is the same as writing:



                        String st1 = "AB";


                        And equal literals are always evaluated to same String object, as told in specification (https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5)




                        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"




                        In your question, you assume that constant pool cannot hold two different instances of the same value, that is right, but that does not imply that every String instance resides in constant pool. In fact, there is no possibility to guaranteely make equal strings created on runtime be the same object, for example:



                        String st1 = "AB";
                        String st2 = new String(st1);
                        String st3 = new String(st1);


                        will result in three different String instances: first as literal evaluation result, taken from constant pool, others as newly constructed objects (though new always creates a new object!). == on them will fail unless you adjust them using String#intern:



                        st1 == st2.intern();  // true





                        share|improve this answer






























                          1














                          The rule you mentioned regards string literals, i.e. pieces of code written in double quotes, like "AB". Result of operation, which may be evaluated on compile time ("constant expression"), is immediately replaced by resulting literal:



                          String st1 = "A" + "B";


                          is the same as writing:



                          String st1 = "AB";


                          And equal literals are always evaluated to same String object, as told in specification (https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5)




                          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"




                          In your question, you assume that constant pool cannot hold two different instances of the same value, that is right, but that does not imply that every String instance resides in constant pool. In fact, there is no possibility to guaranteely make equal strings created on runtime be the same object, for example:



                          String st1 = "AB";
                          String st2 = new String(st1);
                          String st3 = new String(st1);


                          will result in three different String instances: first as literal evaluation result, taken from constant pool, others as newly constructed objects (though new always creates a new object!). == on them will fail unless you adjust them using String#intern:



                          st1 == st2.intern();  // true





                          share|improve this answer




























                            1












                            1








                            1







                            The rule you mentioned regards string literals, i.e. pieces of code written in double quotes, like "AB". Result of operation, which may be evaluated on compile time ("constant expression"), is immediately replaced by resulting literal:



                            String st1 = "A" + "B";


                            is the same as writing:



                            String st1 = "AB";


                            And equal literals are always evaluated to same String object, as told in specification (https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5)




                            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"




                            In your question, you assume that constant pool cannot hold two different instances of the same value, that is right, but that does not imply that every String instance resides in constant pool. In fact, there is no possibility to guaranteely make equal strings created on runtime be the same object, for example:



                            String st1 = "AB";
                            String st2 = new String(st1);
                            String st3 = new String(st1);


                            will result in three different String instances: first as literal evaluation result, taken from constant pool, others as newly constructed objects (though new always creates a new object!). == on them will fail unless you adjust them using String#intern:



                            st1 == st2.intern();  // true





                            share|improve this answer















                            The rule you mentioned regards string literals, i.e. pieces of code written in double quotes, like "AB". Result of operation, which may be evaluated on compile time ("constant expression"), is immediately replaced by resulting literal:



                            String st1 = "A" + "B";


                            is the same as writing:



                            String st1 = "AB";


                            And equal literals are always evaluated to same String object, as told in specification (https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5)




                            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"




                            In your question, you assume that constant pool cannot hold two different instances of the same value, that is right, but that does not imply that every String instance resides in constant pool. In fact, there is no possibility to guaranteely make equal strings created on runtime be the same object, for example:



                            String st1 = "AB";
                            String st2 = new String(st1);
                            String st3 = new String(st1);


                            will result in three different String instances: first as literal evaluation result, taken from constant pool, others as newly constructed objects (though new always creates a new object!). == on them will fail unless you adjust them using String#intern:



                            st1 == st2.intern();  // true






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Nov 14 '18 at 12:49

























                            answered Nov 14 '18 at 11:27









                            Alex SalauyouAlex Salauyou

                            11.1k43359




                            11.1k43359























                                0














                                st1 + " E" 


                                this line of code will reassign



                                String st1 = "C D";
                                st1 += " E";
                                String str2 = "C D E";
                                System.out.println(st1.hashCode() == str2.hashCode()); //True


                                fetch the internal address that same
                                thank u






                                share|improve this answer
























                                • String#hashCode is calculated upon its value, not "internal address"

                                  – Alex Salauyou
                                  Nov 14 '18 at 12:18


















                                0














                                st1 + " E" 


                                this line of code will reassign



                                String st1 = "C D";
                                st1 += " E";
                                String str2 = "C D E";
                                System.out.println(st1.hashCode() == str2.hashCode()); //True


                                fetch the internal address that same
                                thank u






                                share|improve this answer
























                                • String#hashCode is calculated upon its value, not "internal address"

                                  – Alex Salauyou
                                  Nov 14 '18 at 12:18
















                                0












                                0








                                0







                                st1 + " E" 


                                this line of code will reassign



                                String st1 = "C D";
                                st1 += " E";
                                String str2 = "C D E";
                                System.out.println(st1.hashCode() == str2.hashCode()); //True


                                fetch the internal address that same
                                thank u






                                share|improve this answer













                                st1 + " E" 


                                this line of code will reassign



                                String st1 = "C D";
                                st1 += " E";
                                String str2 = "C D E";
                                System.out.println(st1.hashCode() == str2.hashCode()); //True


                                fetch the internal address that same
                                thank u







                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Nov 14 '18 at 11:47









                                vishnu.ppvishnu.pp

                                14




                                14













                                • String#hashCode is calculated upon its value, not "internal address"

                                  – Alex Salauyou
                                  Nov 14 '18 at 12:18





















                                • String#hashCode is calculated upon its value, not "internal address"

                                  – Alex Salauyou
                                  Nov 14 '18 at 12:18



















                                String#hashCode is calculated upon its value, not "internal address"

                                – Alex Salauyou
                                Nov 14 '18 at 12:18







                                String#hashCode is calculated upon its value, not "internal address"

                                – Alex Salauyou
                                Nov 14 '18 at 12:18





                                Popular posts from this blog

                                Xamarin.iOS Cant Deploy on Iphone

                                Glorious Revolution

                                Dulmage-Mendelsohn matrix decomposition in Python