What is the difference between an addition of String Literal and String Object?
For example
String s1 =\"hello\";
String s2 =\"hello1\";
EDIT: I assume that you know that you are comparing references, not the contents of the strings. If no, s3.equals(s5)
is what you are looking for (as already mentioned).
s3
is optimized by the compiler to "hellohello1"
which is reused for s4
as well. I'm quite surprised that the compiler isn't smart enough to do the same for . This optimization is only allowed for constant expressions (see 15.28 of Java Language Specification). In other words, any assignment to a non-final variable denies the possibility of later optimization.s5
though. Which JDK version are you using?
Here's the output of javap -c -l
of a simple class that wraps your code into a main method (not that anybody asked for it, but I'm curious myself). So let's see what's going on:
public static void main(java.lang.String[]);
Code:
0: ldc #16; //String hello
2: astore_1
3: ldc #18; //String hello1
5: astore_2
6: ldc #20; //String hellohello1
8: astore_3
9: ldc #20; //String hellohello1
11: astore 4
13: new #22; //class java/lang/StringBuilder
16: dup
17: aload_1
18: invokestatic #24; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
21: invokespecial #30; //Method java/lang/StringBuilder."":(Ljava/lang/String;)V
24: aload_2
25: invokevirtual #33; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
28: invokevirtual #37; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
31: astore 5
33: getstatic #41; //Field java/lang/System.out:Ljava/io/PrintStream;
36: aload_3
37: aload 4
39: if_acmpne 46
42: iconst_1
43: goto 47
46: iconst_0
47: invokevirtual #47; //Method java/io/PrintStream.println:(Z)V
50: getstatic #41; //Field java/lang/System.out:Ljava/io/PrintStream;
53: aload_3
54: aload 5
56: if_acmpne 63
59: iconst_1
60: goto 64
63: iconst_0
64: invokevirtual #47; //Method java/io/PrintStream.println:(Z)V
67: getstatic #41; //Field java/lang/System.out:Ljava/io/PrintStream;
70: aload 4
72: aload 5
74: if_acmpne 81
77: iconst_1
78: goto 82
81: iconst_0
82: invokevirtual #47; //Method java/io/PrintStream.println:(Z)V
85: return
LocalVariableTable:
Start Length Slot Name Signature
0 86 0 args [Ljava/lang/String;
3 83 1 s1 Ljava/lang/String;
6 80 2 s2 Ljava/lang/String;
9 77 3 s3 Ljava/lang/String;
13 73 4 s4 Ljava/lang/String;
33 53 5 s5 Ljava/lang/String;
}
I'm not to experienced reading byte code, but I'll give it a go :)
ldc #16
followed by astore_1
means "load constant #16 and store it in slot 1". As you can see, this is done 4 times at the beginning for slots 1 - 4 which translates to s1, s2, s3 and s4 (see LocalVariableTable).aload_1
) and slot 2 (aload_2
) involved before storing the result in slot 5 (astore 5
).