java有很多语法糖,比如自动拆箱,自动装箱,foreach等等,这些原理相信每一个入门教程里都有讲,但是我相信不是每一个人
都通过查看这些语法糖的字节码来确认这些原理,因为我也是现在才想看一下。
1.自动拆箱和自动装箱
public void test() { Integer integer = 1; int i = integer; } |
//将常量1放入操作数栈 0: iconst_1 //调用Integer.valueOf 入参为0操作指令压入的1 1: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; //将1操作指令得到的integer存入临时变量表 4: astore_1 //将integer放入操作数栈 5: aload_1 //调用integer.intValue:() 6: invokevirtual #3 // Method java/lang/Integer.intValue:()I 9: istore_2 10: return |
字节码非常清楚的描述了装箱拆箱过程,关于Interger还有一个知识点就是Integer常量池,Integer常量池其实很简单,其实就是Integer内部维护了这样一个数组,这不属于jvm的范围,不再详细介绍
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } |
2.foreach
虽然foreach再java8时代已经过时了,但是我个人还是习惯用它不习惯用Collection.forEach。
public class SyntacticSugarTest { List<String> list = new ArrayList<>(); //语法糖 @Test public void test() { for (String s : list) { } } //jvm实际执行的代码 @Test public void test2(){ Iterator<String> iterator = list.iterator(); while (iterator.hasNext()){ String next = iterator.next(); } } } |
当然这个入门教程里都有讲,那么我们可以看他们两个的字节码来确认一下,完全一样
public void test(); Code: 0: aload_0 1: getfield #4 // Field list:Ljava/util/List; 4: invokeinterface #5, 1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator; 9: astore_1 10: aload_1 11: invokeinterface #6, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z 16: ifeq 32 19: aload_1 20: invokeinterface #7, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object; 25: checkcast #8 // class java/lang/String 28: astore_2 29: goto 10 32: return public void test2(); Code: 0: aload_0 1: getfield #4 // Field list:Ljava/util/List; 4: invokeinterface #5, 1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator; 9: astore_1 10: aload_1 11: invokeinterface #6, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z 16: ifeq 32 19: aload_1 20: invokeinterface #7, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object; 25: checkcast #8 // class java/lang/String 28: astore_2 29: goto 10 32: return } |