JVM-String comparison-bytecode analysis, jvm-string bytecode
Bytecode analysis caused by a String comparison Problem
Public class a {public static void main (String [] args) throws Exception {} public static void aa () {String s1 = ""; // constant pool in the method area String s2 = "B"; // constant pool in the method area String s12 = "AB "; // There is a constant pool in the method area. String s3 = s1 + s2; // The s3 memory is located ??? P (s3 = s12); // false} public static void bb () {String s1 = "a" + "B"; // the memory of s1 ??? String s2 = "AB"; // The constant pool p (s1 = s2) IN THE METHOD area exists; // true} public static void p (Object obj) {System. out. println (obj );}}
This is an annoying String comparison problem we often encounter. To obtain the answer, we need to find out where s3 exists in the aa () method ?, And where does s1 exist in the bb () method?
Not to mention, paste the bytecode command decompiled in the. class file:
The first is the aa () method:
Public static void aa (); flags: ACC_PUBLIC, ACC_STATIC Code: stack = 2, locals = 4, args_size = 0 a total of 4 local variable spaces 0: ldc #3 // String a pushes the String "a" from the constant pool to the top of the stack. 2: astore_0 pushes the top reference type of the stack (that is, the String "") store the first local variable 3: ldc #4 // String B to push String "B" from the constant pool to the top 5 of the stack: astore_1 saves the stack top reference type (that is, the string "B") to the second local variable 6: ldc #5 // String AB pushes the String "AB" from the constant pool to the top of the stack 8: astore_2 push the top stack reference type (that is, the String "AB ") store the third local variable 9: new #6 // class java/lang/StringBuilder to create the StringBuilder object sb, and press the reference value to the top of the stack 12: dup to copy the top number of the stack, and press the copy value to the top of the stack 13: invokespecial #7 // Method java/lang/StringBuilder. call the initialization method of the object "<init>" :() V 16: aload_0 push the first local variable (that is, the string "a") to the top 17 of the stack: invokevirtual #8 // Method java/lang/StringBuilder. call the instance method sb. append ("a"); append :( Ljava/lang/String;) Ljava/lang/StringBuilder; 20: aload_1 place the second local variable (that is, the String "B ") push to stack top 21: invokevirtual #8 // Method java/lang/StringBuilder. call the instance method sb. append ("B"); append :( Ljava/lang/String;) Ljava/lang/StringBuilder; 24: invokevirtual #9 // Method java/lang/StringBuilder. call the instance method sb. toString (), and place the result [Java heap address] on the top of the stack toString :() Ljava/lang/String; 27: astore_3. The top stack reference type (that is, the heap address) store the fourth local variable 28: aload_3 push the fourth local variable (heap address) to the top of the stack 29: aload_2 push the third local variable (that is, the string "AB ") push to the top 30: if_acmpne 37 of the stack to compare the two reference values on the top of the stack. The results are different (of course different) 33: iconst_1 34: goto 38 37: iconst_0: Press int Type 0 to the top of stack 38: invokestatic #10 // Method java/lang/Boolean. valueO calls the static method Boolean. valueOf (); implement the basic data type-> automatically convert the packaging type f :( Z) Ljava/lang/Boolean; 41: invokestatic #11 // Method p :( Ljava/lang/Object;) V calls the static Method p (false); // outputs false 44: return returns void from the current Method
Here are some explanations: (the following number is the bytecode offset)
24 why do I talk about [heap address] in sb. toString ()? You can see the source code.
// This is the source code of StringBuilder. The returned String address is public String toString () {return new String (value, 0, count );}
Therefore, in the aa () method, s3 memory is actually on the Java stack, and s12 is on the constant pool of the method area, so the two are not equal.
37 boolean is allocated several bytes, which can be seen here.
If it is true, the byte code translated by the compiler is iconst_1, meaning that int type 1 is saved to the top of the stack. Therefore, when a single boolean value is referenced, four bytes are allocated, which is the same as int. (Array boolean is not tested. It is not clear)
If it is false, the byte code translated by the compiler is iconst_0, meaning that int Type 0 is saved to the top of the stack.
38 here we can also see the figure of automatic type conversion. Here is the basic data type boolean-> the automatic type conversion of the packaging type Boolean, actually called Boolean. valueOf () static method, because the following p () method requires the Object reference type, so automatic type conversion is performed.
Then the bb () method:
Public static void bb (); flags: ACC_PUBLIC, ACC_STATIC Code: stack = 2, locals = 2, args_size = 0 two local variable spaces 0: ldc #5 // String AB pushes the String "AB" from the constant pool to the top of the stack 2: astore_0 store the top reference type (String "AB") of the stack to the first local variable 3: ldc #5 // String AB pushes the String "AB" from the constant pool to the top 5: astore_1 of the stack, and saves the top reference type (String "AB") of the stack to the first local variable 6: aload_0 pushes the first local variable ("AB") to the top of the stack 7: aload_1 pushes the second local variable ("AB") to the top of the stack 8: if_acmpne 15 compares the values of the two reference types on the top of the stack, and the results are different jumps (of course the same here) 11: iconst_1 pushes int type 1 to the top of the stack 12: goto 16 jump to 16 bytecode offset unconditionally 15: iconst_0 16: invokestatic #10 // Method java/lang/Boolean. valueO calls the static method Boolean. valueOf (); and press true of the returned Boolean type to the top of the stack f :( Z) Ljava/lang/Boolean; 19: invokestatic #11 // Method p :( Ljava/lang/Object;) V calls the static Method p (true); outputs true 22: return returns void from the current Method
Here are some explanations: (the following number is the bytecode offset)
0. the compiler will see the String a = "aa" + "bb"; will be automatically merged, "aabb" will be saved to the constant pool, and the return address will be returned. So the answer is true.