最近群友抛出了一个面试题,就是下图中的第二题,是关于一个for循环的执行结果的问题,他的代码的执行结果是什么呢? java
下面的例子和面试题上面的大同小异,是个很是简单的例子。首先这个代码是能够编译经过的,也能够正常执行的。那么执行结果是什么呢?会跟咱们猜测的同样吗?git
/** * Created by baiguantao on 2017/10/20. */ public class T { public static boolean testA(char a){ System.out.print(a); return true; } /** * for循环的一些疑问 * @param args */ public static void main(String[] args) { int i=0; for (testA('a');testA('b')&&(i<2);testA('c')) { i++; testA('d'); } } }
abdcbdcb面试
那么问题来了,为何是这个结果呢?咱们能够借助javap命令反编译咱们刚才编译的T.class进行分析。 若是对jvm不了解的能够参阅JVM基础。jvm
C:\Users\temp\IdeaProjects\mix_learn\target\classes>javap -c T.class Compiled from "T.java" public class T { public T(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static boolean testA(char); Code: 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: iload_0 4: invokevirtual #3 // Method java/io/PrintStream.print:(C)V 7: iconst_1 8: ireturn public static void main(java.lang.String[]); Code: 0: iconst_0 1: istore_1 2: bipush 97 4: invokestatic #4 // Method testA:(C)Z 7: pop 8: bipush 98 10: invokestatic #4 // Method testA:(C)Z 13: ifeq 39 16: iload_1 17: iconst_2 18: if_icmpge 39 21: iinc 1, 1 24: bipush 100 26: invokestatic #4 // Method testA:(C)Z 29: pop 30: bipush 99 32: invokestatic #4 // Method testA:(C)Z 35: pop 36: goto 8 39: return }
对反编译后的文件是否是一脸懵逼,没太看懂是什么意思呢?不要紧,下面咱们进行逐行分析。函数
C:\Users\temp\IdeaProjects\mix_learn\target\classes>javap -c T.class Compiled from "T.java" public class T { public T(); // 这里是默认生成的无参构造函数部分开始 Code: 0: aload_0 //表示对this的操做 1: invokespecial #1 // Method java/lang/Object."<init>":()V 调用特殊实例方法 4: return // 返回结果 // 这里是默认生成的无参构造函数部分结束 public static boolean testA(char);// 这里是咱们写入的静态方法 Code: 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; System.out调用类方法 3: iload_0 //从局部变量表中加载int型的数据到操做数栈 4: invokevirtual #3 // Method java/io/PrintStream.print:(C)V 调用实例方法 7: iconst_1 //int类型0进栈 8: ireturn // 返回结果 public static void main(java.lang.String[]); Code: 0: iconst_0 //int类型0进栈 1: istore_1 // int类型1出栈 2: bipush 97 // byte型常量97(a)进栈 4: invokestatic #4 // Method testA:(C)Z 执行静态方法testA 7: pop // 栈顶数值出栈(不能是long/double) 8: bipush 98 // byte型常量98(b)进栈 10: invokestatic #4 // Method testA:(C)Z 执行静态方法testA 13: ifeq 39 //判断语句 是否相等 循环结束 跳转到39 16: iload_1 //从局部变量表中加载int型的数据到操做数栈 17: iconst_2 //int类型2进栈 18: if_icmpge 39 //比较栈顶两int型数值大小,当结果大于等于0时跳转到39的位置 21: iinc 1, 1 //给局部变量表的1号位置的int值增长1 24: bipush 100 // byte型常量100(d)进栈 26: invokestatic #4 // Method testA:(C)Z 执行静态方法testA 29: pop // 栈顶数值出栈(不能是long/double) 30: bipush 99 // byte型常量99(c)进栈 32: invokestatic #4 // Method testA:(C)Z 执行静态方法testA 35: pop // 栈顶数值出栈(不能是long/double) 36: goto 8 // 从新循环 到8的位置 39: return //退出循环 }
总体上的结构this
for循环执行流程spa
从反编译文件以及流程图中咱们能够看出for循环执行的顺序是:.net
因此咱们的执行输出结果是:abdcbdcbblog
不对之处还望你们指正。ip
做者 ricky
交流群:244930845