Saturday, 27 May 2017

string - Differences between "abc" + "de" and "abc" + de (de = "de") in Java?



I run the following code and get the results shown in the comments. I know the differences between == and .equals(). What I don't understand is why my code in the second line has different results from the code in the third line.



    String de = "de";
// String abcde = "abc" + "de"; // abcde == "abcde" reture true
String abcde = "abc" + de; // abcde == "abcde" reture false;
System.out.println();
System.out.println(abcde=="abcde");
System.out.println(de=="de");



In trying to debug this I used the javap -c command and got the following output 'code' for the first string concatenation:



         Code:
0: ldc #9; //String de
2: astore_1
3: new #10; //class java/lang/StringBuilder
6: dup
7: invokespecial #11; //Method java/lang/StringBuilder."":()V

10: ldc #4; //String abc
12: invokevirtual #12; //Method java/lang/StringBuilder.append:(Ljava/lang
String;)Ljava/lang/StringBuilder;
15: aload_1
16: invokevirtual #12; //Method java/lang/StringBuilder.append:(Ljava/lang
String;)Ljava/lang/StringBuilder;
19: invokevirtual #13; //Method java/lang/StringBuilder.toString:()Ljava/l
ng/String;
22: astore_2
23: getstatic #14; //Field java/lang/System.out:Ljava/io/PrintStream;

26: invokevirtual #15; //Method java/io/PrintStream.println:()V
29: getstatic #14; //Field java/lang/System.out:Ljava/io/PrintStream;
32: aload_2
33: ldc #16; //String abcde
35: if_acmpne 42
38: iconst_1
39: goto 43
42: iconst_0
43: invokevirtual #17; //Method java/io/PrintStream.println:(Z)V
46: getstatic #14; //Field java/lang/System.out:Ljava/io/PrintStream;

49: aload_1
50: ldc #9; //String de
52: if_acmpne 59
55: iconst_1
56: goto 60
59: iconst_0
60: invokevirtual #17; //Method java/io/PrintStream.println:(Z)V
63: return



And the output for the second string concatenation:





I am not so familiar with this 'code' and can't see any reason why these differences exists. So could anyone explain why those differences happen?



Related post


Answer



The "problem" is simply that the compiler is too smart for you. When it sees "abc" + "de" it immediately concatenates that into the literal "abcde". But when it sees "abc" + de it's not allowed (per Java rules) to "optimize" that to a literal but must instead implement the + function, creating a new String object.




String literals are always handled as interned Strings, so == will work on them.


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...