疑问
     最近群友抛出了一个面试题,就是下图中的第二题,是关于一个for循环的执行结果的问题,他的代码的执行结果是什么呢? 
   
  
   代码复现
     下面的例子和面试题上面的大同小异,是个非常简单的例子。首先这个代码是可以编译通过的,也可以正常执行的。那么执行结果是什么呢?会跟我们猜想的一样吗?
  
  /**  * 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基础。
   反编译
     - 先贴出原版的字节码反编译后的代码,后边会对反编译的文件进行逐行解析,那么我们先来看看上述类反编译后的样子吧。如下所示:
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                            //退出循环 }       整体上的结构 
  
     for循环执行流程 
  
   总结
     从反编译文件以及流程图中我们可以看出for循环执行的顺序是:
  
     - testA(a)
- testA('b')
- testA('d')
- testA('c')
- testA('b')
- testA('d')
- testA('c')
- testA('b')
所以我们的执行输出结果是:abdcbdcb
   最后
  不对之处还望大家指正。
  作者 ricky
  交流群:244930845