Originated in: https://www.cnblogs.com/tomasman/p/6751751.html
There are some difficulties in knowing the underlying foreach directly, and we need to start with a simpler example. The following is a simple example:
1 public class Simple {2 3 public static void Main (string[] args) {4 int i = 5;5 System.out.println (i); 6 } 7}
Locate the directory where the bytecode file is located and open the terminal in the directory (the Windows system is in the directory shift+ the right mouse button is selected to open the PowerShell window)
Input instruction: Javac-simple.class >simplerunc
The directory to get the Simplerunc file, open it, you will see the following code (there is my comment):
1 Compiled from ' Simple.java ' 2 public class Cn._012thday._foreach. Simple {3 public Cn._012thday._foreach. Simple (); 4 code:5 0:aload_0 pushes the first reference local variable to the top of the stack, and 6 1:invokespecial #8 //Method java/lang/object. " <init> ":() V 7 calls the superclass construction method, 8 4:return 9 public static void Main (java.lang.string[]); code:12< C10/>0:iconst_5 the INT type 5 to the top of the stack; 1:istore_1 the top int data into the second local variable; the first local variable is the superclass; 15 16 17 2:getstatic #16 //Field java/lang/system.out:ljava/io/printstream;18 gets the local static domain and presses it into the top of the stack; That is to get the static property pressed into the stack top 5:iload_1 pushes the second int type local variable to the top of the stack; 6:invokevirtual #22 //Method java/io/ Printstream.println: (I) V21 Invoke instance method; get class properties, load into stack, print top of stack, i.e. 523 9:return25}
If you do not understand the instructions, you can query the JVM instruction table. Here I explain the steps:
First step: Loading the Super Class object class
Step Two: Press 5 of the int type into the top of the stack and then save 5 to local variable 1
Part III: getting static properties
Fourth step: Load local variable 1, push 5 to the top of the stack
Fifth Step: Print
For loop
1 public class Forsimple {2 3 publicly static void main (string[] args) {4 for (int i = 5; i > 0; i-=2) {5 Sys Tem.out.println (i); 6 }7 }8}
In fact, this example does not work with foreach because the foreach traversal must have an array.
Javap-c:
Compiled from the "Forsimple.java" public class Cn._012thday._foreach. forsimple {public Cn._012thday._foreach. Forsimple (); Code: 0:aload_0 1:invokespecial #8 //Method java/lang/object. " <init> ":() V 4:return public static void Main (java.lang.string[]); Code: 0:iconst_5 1:istore_1 2:goto 5:getstatic #16 //Field java/lang/ System.out:ljava/io/printstream; 8:iload_1 9:invokevirtual #22 //Method java/io/printstream.println: (I) V 12:iinc 1,-2 15 : Iload_1 16:ifgt 5 19:return}
The Main method, line 2nd, Goto 15, represents the unconditional jump to line 15th load variable 1, the value is 5
16 Row: IFGT 5 if the int type is greater than zero, go back to line 5th, 5>0
5~9 Line: Print, 5
12 Rows: Variable 1 self-increment-2, or 5 becomes 3
15 Rows: Load variable 1 with a value of 3
16 Row: IFGT 5 if the int type is greater than zero, go back to line 5th, 3>0
5~9 Line: Print, 3
12 Rows: Variable 1 self-increment-2, or 3 becomes 1
15 Rows: Load variable 1 with a value of 1
16 Row: IFGT 5 if the int type is greater than zero, go back to line 5th, 1>0
5~9 Line: Print, 1
12 Rows: Variable 1 self-increment-2, or 1 becomes-1
15 Rows: Load variable 1, value is-1
16 Row: IFGT 5 if the int type is greater than zero, go back to line 5th, -1 <0
19 Line: Return Main method End
The For loop prints the result as 5,3,1
foreach traversal
Start with a new int[] array to see how the data is stored:
1 public class Simpledemo {2 3 public static void Main (string[] args) {4 //TODO auto-generated method stub 5 Int[]arr = new Int[3]; 6 arr[0] = 7 arr[1] = 8 arr[2] =; 9 }10}
Compiled from the "Simpledemo.java" public class Cn._012thday._foreach. Simpledemo {public Cn._012thday._foreach. Simpledemo (); Code: 0:aload_0 1:invokespecial #8 //Method java/lang/object. " <init> ":() V 4:return public static void Main (java.lang.string[]); Code: 0:iconst_3 1:newarray int 3:astore_1 4:aload_1 5:iconst_0 6:bipush Ten 8:iastore 9:aload_1 10:iconst_1 11:bipush 13:iastore 14:aload_1 15:iconst_2 16:bipush 18:iastore 19:return}
The first 3 lines create an array of primitive type (int), 3 in length, and a local reference variable of 1
Press the index 0 position into 10 and store
Press the index 1 position into 20 and store
Press the index 2 position into 30 and store
Next, start the traversal and join the FOR loop:
for (int i = 0; i < arr.length; i++) {
System.out.println (Arr[i]);
}
Compiled from the "Simpledemo.java" public class Cn._012thday._foreach. Simpledemo {public Cn._012thday._foreach. Simpledemo (); code:0: Aload_0 1:invokespecial #8//Method java/lang/object. " <init> ":() V 4:return public static void Main (java.lang.string[]); code:0: iconst_3 1:newarray int 3:astore_1 4:aload_1 5:iconst_0 6:bipush Ten 8:iastore 9:aload_1 10:iconst_1 11:bipush 13:iastore 14:aload_1 15:iconst_2 16:bipush 18:iastore 19:iconst_0 20:istore_2 21:goto 36 24:getstatic #16//Field Java/lang/system.out:ljava/io/printstream; 27:aload_1 28:iload_2 29:iaload 30:invokevirtual #22//Method Java/io/printstream.prin TLN: (I) V 33:iinc 2, 1 36:iload_2 37:aload_1 38:arraylength 39:if_icmplT-42:return}
The above code everyone should be not so strange, the first 18 rows into the array, the 19th line began to create a new variable int value of 0, stored in the variable 2. Then the variable 2 and array length are compared, and the length of the arrays is less than the number of lines to go back to line 24th, which is a typical for loop.
The entire traversal does not consider the loading of the superclass altogether creates two local variables, i.e. arr[3] and int i, compared with arr[3] length 3 and I, conforming to the conditional output ARR[I]. The output is 10,20,30
Now it's our turn to be the main character, foreach, to remove the for loop and add a foreach iteration:
for (int item:arr) {
SYSTEM.OUT.PRINTLN (item);
}
Compiled from the "Simpledemo.java" public class Cn._012thday._foreach. Simpledemo {public Cn._012thday._foreach. Simpledemo (); code:0: Aload_0 1:invokespecial #8//Method java/lang/object. " <init> ":() V 4:return public static void Main (java.lang.string[]); code:0: iconst_3 1:newarray int 3:astore_1 4:aload_1 5:iconst_0 6:bipush Ten 8:iastore 9:aload_1 10:iconst_1 11:bipush 13:iastore 14:aload_1 15:iconst_2 16:bipush 18:iastore 19:aload_1 load local1:0 20:dup copy 21:astore 5 int[] local5 = Local1 23:arraylength 3 2 4:istore 4 int local4 = 3 26:iconst_0 0 27:istore_3 int local3 = 0 2 8:goto 31:aload 5 load local5:int[3] 33:iload_3Load local3:0. 34:iaload arr[0 ...] into the stack 35:istore_2 int local2 = arr[0 ...] 36:getstatic #16//Field Java/lang/system.out:ljava/io/printstream; 39:iload_2 load local2:arr[0 ...] 40:invokevirtual #22//Method java/io/printstream.println: (I) V 43:iinc 3, 1 Local3 +=1 46:iload_3 load local3:0. 47:iload 4 Load Local4:3 49:if_icmplt Local3 < Local4? Go line31:next line 52:return}
The above code I added the comments, here should be able to understand, regardless of the superclass loading, foreach created 5 local variables:
Local1 is the original array, the reference type
LOCAL5 is a copy of the original array, the reference type
Local4 is the copy array length, int type
Local3 is the 0,int type
Local2 is a copy of arr[i], int type
Summarize:
1.for Loop and foreach loop the underlying creation of the variable number is different, for the traversal int[] Type array, the For loop underlying creates 2 local variables, while the foreach bottom creates 5 local variables;
The 2.for Loop operates directly on the array, and the foreach array copy operates;
Because foreach is an array copy operation, problems that may be caused in development are:
Attach Java code and JAVAP-C code
1 public class Foreachdemo {2 3 public static void Main (string[] args) {4 //TODO auto-generated method stub 5 6 string[] S1 = new String[3]; 7 for (String item:s1) {//S1 here is actually s1 copy 8 item = new String ("B"); 9
SYSTEM.OUT.PRINTLN (item);//You can print}11 print (S1) for each item in the copy ,//print S1 is null, because S1 does not change in memory address. }14 The private static void print (string[] s) { //TODO auto-generated method stub17 for (int i = 0; I < S. Length i++) { System.out.print (s[i]+ "); }20 }21 22}
Compiled from the "Foreachdemo.java" public class Cn._012thday._foreach. Foreachdemo {public Cn._012thday._foreach. Foreachdemo (); code:0: Aload_0 1:invokespecial #8//Method java/lang/object. " <init> ":() V 4:return public static void Main (java.lang.string[]); code:0: Iconst_3 1:anewarray #16//class java/lang/string 4:astore_1 5:al Oad_1 6:dup 7:astore 5 9:arraylength 10:istore 4 12:iconst_0 13:istor E_3 14:goto 17:aload 5 19:iload_3 20:aaload 21:astore_2 22:new #16//Class java/lang/string 25:dup 26:LDC #18//String b 28:invokespecial #20//Method java/lang/string. " <init> ":(ljava/lang/string;) V 31:astore_2 32:getstatic #23//Field Java/lang/system . out:ljava/io/PrintStream; 35:aload_2 36:invokevirtual #29//Method java/io/printstream.println: (ljava/lang/string;) V 39 : Iinc 3, 1 42:iload_3 43:iload 4 45:if_icmplt 48:aload_1 49:invokes Tatic #34//Method print: ([ljava/lang/string;) V 52:return}
Javap-c code Line 7th creates a new string[] array copy variable 5, and then continues to operate on the copy until the 48 lines aload_1 and then print, it is not difficult to see that all operations in foreach do not have any effect on the value of local variable 1 (that is, the original array).
So the last line of the main method prints the array s1, which must have a result of 3 null
How to view the bytecode (original code) of a. java file