代码如下
public class Test2 {
static long[] images = new long[]{1,2,3,4,5,6,7};
public static void main(String[] args) {
}
private static void format1() throws InterruptedException {
for (int i = 0; i < images.length; i++) {
Thread.sleep(images[i]);
}
}
private static void format2() throws InterruptedException {
int length =images.length;
for (int i = 0; i < length; i++) {
Thread.sleep(images[i]);
}
}
}
如果不明白java 内存结构的建议先去学习下java 内存结构。
- 我们的方法在栈中运行 栈内存结构如下:
- 这里需要理解的是 局部变量指的是 基本数据类型
那么 问题是 format2 中的 length 到底是在局部变量中 还是在别的地方 比如常量池
解答如下
首先是通过idea 中 打开字节码文件
展示如下:
/ class version 52.0 (52)
// access flags 0x21
public class com/lagou/example/first/week17/Test2 {
// compiled from: Test2.java
// access flags 0x8
static [J images
// access flags 0x1
public <init>()V
L0
LINENUMBER 8 L0
ALOAD 0
INVOKESPECIAL java/lang/Object.<init> ()V
RETURN
L1
LOCALVARIABLE this Lcom/lagou/example/first/week17/Test2; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x9
public static main([Ljava/lang/String;)V
// parameter args
L0
LINENUMBER 14 L0
RETURN
L1
LOCALVARIABLE args [Ljava/lang/String; L0 L1 0
MAXSTACK = 0
MAXLOCALS = 1
// access flags 0xA
private static format1()V throws java/lang/InterruptedException
L0
LINENUMBER 17 L0
ICONST_0
ISTORE 0
L1
FRAME APPEND [I]
ILOAD 0
GETSTATIC com/lagou/example/first/week17/Test2.images : [J
ARRAYLENGTH
IF_ICMPGE L2
L3
LINENUMBER 18 L3
GETSTATIC com/lagou/example/first/week17/Test2.images : [J
ILOAD 0
LALOAD
INVOKESTATIC java/lang/Thread.sleep (J)V
L4
LINENUMBER 17 L4
IINC 0 1
GOTO L1
L2
LINENUMBER 20 L2
FRAME CHOP 1
RETURN
LOCALVARIABLE i I L1 L2 0
MAXSTACK = 2
MAXLOCALS = 1
// access flags 0xA
private static format2()V throws java/lang/InterruptedException
L0
LINENUMBER 23 L0
GETSTATIC com/lagou/example/first/week17/Test2.images : [J
ARRAYLENGTH
ISTORE 0
L1
LINENUMBER 24 L1
ICONST_0
ISTORE 1
L2
FRAME APPEND [I I]
ILOAD 1
ILOAD 0
IF_ICMPGE L3
L4
LINENUMBER 25 L4
GETSTATIC com/lagou/example/first/week17/Test2.images : [J
ILOAD 1
LALOAD
INVOKESTATIC java/lang/Thread.sleep (J)V
L5
LINENUMBER 24 L5
IINC 1 1
GOTO L2
L3
LINENUMBER 27 L3
FRAME CHOP 1
RETURN
L6
LOCALVARIABLE i I L2 L3 1
LOCALVARIABLE length I L1 L6 0
MAXSTACK = 2
MAXLOCALS = 2
// access flags 0x8
static <clinit>()V
L0
LINENUMBER 10 L0
BIPUSH 7
NEWARRAY T_LONG
DUP
ICONST_0
LCONST_1
LASTORE
DUP
ICONST_1
LDC 2
LASTORE
DUP
ICONST_2
LDC 3
LASTORE
DUP
ICONST_3
LDC 4
LASTORE
DUP
ICONST_4
LDC 5
LASTORE
DUP
ICONST_5
LDC 6
LASTORE
DUP
BIPUSH 6
LDC 7
LASTORE
PUTSTATIC com/lagou/example/first/week17/Test2.images : [J
RETURN
MAXSTACK = 5
MAXLOCALS = 0
}
可以参考下 字节码 对照表
https://www.cnblogs.com/sheeva/p/6279096.html
可以看到 format1 每次都会去堆中读取 数组的长度信息
而 format2 的int length 数据类型 属于 局部变量
可以对应上面网址中字节码的信息 大家对比下
There is a no tomorrow !!!