专栏原创出处:github-源笔记文件 (opens new window)github-源码 (opens new window),欢迎 Star,转载请附上原文出处链接和本声明。

Java 核心知识专栏系列笔记,系统性学习可访问个人复盘笔记-技术博客 Java 核心知识 (opens new window)

# 个人想法

总结此文章源于以前对代码格式书写的误解。本文涉及字节码相关内容可参考末尾《Java JVM(JDK13)-专栏文章目录汇总》专栏中字节码博文。

# for 里面外面声明对象问题

// 方式一:Object 声明在 for 外部
public void forObjectOutline() {
    Object o;
    for (int i = 0; i < 10; i++) {
        o = new Object();
        System.out.println(o);
    }
}

// 方式二:Object 声明在 for 内部
public void forObjectInline() {
    for (int i = 0; i < 10; i++) {
        Object o = new Object();
        System.out.println(o);
    }
}

上面的代码哪种写法性能更优?答案是都一样。最终生成的字节码为方式二的写法。

因为不管你在哪儿声明的对象 o,虚拟机中的栈帧只为这个 o 创建一个对应的局部变量槽。for 里面的 new 操作只是一直将 o 引用重新指向新的对象而已。

方式二字节码如下:

Code:(字节码)
  stack=2, locals=3, args_size=1
     0: iconst_0
     1: istore_2
     2: iload_2
     3: bipush        10
     5: if_icmpge     29    for 的条件判断
     8: new           #3    new java/lang/Object
    11: dup                 赋值一份 new 出来的引用
    12: invokespecial #1    调用构造方法 java/lang/Object."<init>":()V
    15: astore_1            将栈顶引用型数值(刚刚 new 出来的对象)存入第二个本地变量。即局部变量表中的 o
    16: getstatic     #4    
    19: aload_1
    20: invokevirtual #5    
    23: iinc          2, 1
    26: goto          2
    29: return
  LocalVariableTable:(局部变量表)
    Start  Length  Slot  Name   Signature
       16      13     1     o   Ljava/lang/Object;
        2      27     2     i   I
        0      30     0  this   Lio/groud/leetcode/algorithms/_bytecode/S;

更多相关专栏内容汇总:

最后修改时间: 2/22/2020, 4:51:12 PM