Java foreach Implementation principle

Source: Internet
Author: User
Tags variable scope

Java foreach syntax sugar implementation principle

First, the sample code

1 Importjava.util.ArrayList;2 Importjava.util.List;3 4 /**5  * 6  * @authorLulei7 * @date 2014-9-238  * 9  */Ten  Public classTestforeach { One  A     Privatelist<string> list =NewArraylist<string>(); -     Privatestring[] Array =NewString[10]; -  the     voidTestcollect () { -          for(String str:list) { - System.out.println (str); -         } +     } -  +     voidTestarray () { A          for(String Str:array) at System.out.println (str); -     } -}

Second, byte code

voidTestcollect (); Code:0: Aload_01:getfield #4//Field list:ljava/util/list;4:invokeinterface #7, 1//Interfacemethod Java/util/list.iterator: () Ljava/util/iterator;9: Astore_110: Aload_111:invokeinterface #8, 1//Interfacemethod Java/util/iterator.hasnext: () Z16:ifeq 39 19: Aload_120:invokeinterface #9, 1//Interfacemethod Java/util/iterator.next: () Ljava/lang/object;25:checkcast #5//class Java/lang/string28: astore_229:getstatic #10//Field Java/lang/system.out:ljava/io/printstream;32: Aload_233:invokevirtual #11//Method java/io/printstream.println: (ljava/lang/string;) V36:Goto10 39:return          voidTestarray (); Code:0: Aload_01:getfield #6//Field array:[ljava/lang/string;4: Astore_15: Aload_16: Arraylength7: istore_28: Iconst_09: Istore_310: Iload_311: Iload_212:IF_ICMPGE 34 15: Aload_116: Iload_317: Aaload18:astore 4 20:getstatic #10//Field Java/lang/system.out:ljava/io/printstream;23:aload 4 25:invokevirtual #11//Method java/io/printstream.println: (ljava/lang/string;) V28:iinc 3, 1 31:Goto10 34:return

Third, comments

void testcollect ();

You can see that this is when a Java virtual machine is compiled, a foreach of the collection container type is transformed into an iterative traversal using iterators, and we only explicitly declare a local variable (str) in the source code, but after the compiler has compiled it has used the slot labeled 2 (this, respectively). Used by the ITERATOR,STR). This is the temporary variable that is generated by the foreach syntax sugar when it is compiled by the virtual machine.

0:aload_0//load this from the storage stack frame to the Operation Stack frame1:getfield #4//load the list member variable onto the action stack frame4:invokeinterface #7, 1//Call the List.iterator () method to return the iterator temporary iteration variable to the action stack frame9:astore_1// stores a reference to the newly returned iteration variable on the stack frame stack frame in slot 1th of the storage stack frame10:aload_1// load the reference of the iteration variable in slot 1th to the operation Stack frame11:invokeinterface #8, 1// Call the Hasnext () method of the iterator interface declaration, return a Boolean (actually 0 or 1) to the Operation Stack16:ifeq 39// if 0 is returned, it is transferred to the end of the program19:aload_1// Otherwise, load the temporary iteration variable in slot # 1th into the Operation Stack frame20:invokeinterface #9, 1// call the next () method of the temporary iteration variable to return the current string instance    25:checkcast #5 // checks if the reference type when the previous step was returned is a string type28:astore_2// saves the returned string object from the action stack to the storage stack29:getstatic #10// load an Out object onto the action stack frame32:aload_2// load the string object in slot 2nd onto the action stack frame33:invokevirtual #11// call the Println method of an Out object36:Goto10// Loop continues39:return        

void testarray ();

In the following analysis you will see that the array of foreach syntax sugar at compile time is decomposed into a for-like loop (exactly the while loop), and there is no new virtual machine instruction to use compared to the normal loop statement.

0: Aload_0 // load this from storage stack frame to Operation Stack frame         1:getfield #6// load the array member variable onto the action stack frame 4: Astore_1 //The array in the operation stack frame is stored in slot 1th in the storage stack frame         5: Aload_1 // the array in the storage stack is load into the operation Stack frame         6: Arraylength //Calculate the length of the array reference        7: istore_2 // Save the length of the array to slot 2nd in the storage stack frame         8: Iconst_0 // press constant 0 into the operation Stack frame         9: Istore_3 // Save the constant 0 in the stack frame to the storage stack frame # 3rd slot        10: Iload_3 // load the constant 0 in the 3rd slot in the storage stack frame onto the stack frame (array subscript count variable)        11: Iload_2 // load the length value of the array in the storage stack frame 2nd slot into the Operation Stack frame        12:IF_ICMPGE 34//Compare the access subscript of the array in the stack frame to the length of the array, or the end of the jump program if equal15: Aload_1 //The array referenced in slot 1th in the storage stack frame is load into the Operation Stack       16: Iload_3 //The array stored in slot 3rd in the storage stack frame access subscript variable load into the operation Stack frame       17: Aaload //String reference to the corresponding subscript position in the current action stack frame of the array load into the action stack frame        18:astore 4//The string reference on the action stack frame is stored in slot 4th of the storage stack frame20:getstatic #10// load an Out object onto the action stack frame 23:aload 4//Load a string variable from the 4th slot in the storage stack frame into the Operation Stack25:invokevirtual #11// Call the Println method of an Out object 28:iinc 3, 1//Add 1 to the value of slot 3rd in the storage stack frame and save to the original position (array subscript plus 1)31:Goto10//Resume Loop34:return      

Iv. Summary

1, since there is no "new material nature of things", then why use it?

There is nothing new, and there is no effect on the direction of efficiency, but it can be found here that the loop variable (the iteration variables generated at compiler compile time and array access to the bottom variable) are hidden inside the loop statement, so that the scope of the local variable is reduced, as mentioned in the effective Java book, This prevents variable scope contamination, which can be detected at compile time if a variable that is misused is scoped. It is more important to do this in some cases to reduce the length of the stack frame in the function call stack frame. Of course, if modern virtual machines have active analysis optimization, this part of the problem can be optimized.

2, note what is that part of Mark's Checkcast bytecode?

In fact, this has nothing to do with the foreach syntax sugar, but this is a generic problem because Java generics are using Checkcast-

Java foreach Implementation principle

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.