• 从jvm角度来解析java语法糖


    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
    }
  • 相关阅读:
    java读取properties 属性文件
    oracle中插入一条数据,id自动增长,插入之后怎么得到这个id(sequence的使用)
    Android布局实现圆角边框
    TabHost中使用startActivityForResult无法接收返回值的解决方案[转]
    ORA00937: not a singlegroup group function
    MVC与WebForm最大的区别
    使用SQL Server存储ASP.NET Session变量
    JS中的event 对象详解
    一列多行值合并成一个值(MS SQL SERVER 2008)
    c#如何共享程序集
  • 原文地址:https://www.cnblogs.com/zhandouBlog/p/10350045.html
Copyright © 2020-2023  润新知