最近羣友拋出了一個面試題,就是下圖中的第二題,是關於一個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