java 面试for循环_你真的了解For循环吗?一道For循环Java面试题引发的思考

一,疑问

最近群友抛出了一个面试题,就是下图中的第二题,是关于一个for循环的执行结果的问题,他的代码的执行结果是什么呢?

f0b72c20b1a5b0f48a2eb661ec4d54c9.png

二,代码复现

下面的例子和面试题上面的大同小异,是个非常简单的例子。首先这个代码是可以编译通过的,也可以正常执行的。那么执行结果是什么呢?会跟我们猜想的一样吗?

/**

* 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.classCompiled from "T.java"public class T {

public T();

Code:

0: aload_0

1: invokespecial #1 // Method java/lang/Object."":()V

4: returnpublic 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.classCompiled from "T.java"public class T {

public T(); // 这里是默认生成的无参构造函数部分开始 Code:

0: aload_0 //表示对this的操作

1: invokespecial #1 // Method java/lang/Object."":()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 //退出循环}

流程图

整体上的结构:

737e8f1ddfdf0d35c0daff3b1d423121.png

for循环执行流程

f3da23dc6f92d4251dd0ae3acf5cb87b.png

四,总结

从反编译文件以及流程图中我们可以看出for循环执行的顺序是:

testA(a)

testA('b')

testA('d')

testA('c')

testA('b')

testA('d')

testA('c')

testA('b')

所以我们的执行输出结果是:abdcbdcb

五,最后

本次投稿作者:ricky,java领域专家!

更多精彩,请戳除破这里:https://my.oschina.net/lt0314

推荐阅读:2T架构师教学视频分享

6f2e599c23c403dce20190a9e1b397c8.png

651134.html

架构师小秘圈,聚集10万架构师的小圈子!不定期分享技术干货,行业秘闻!汇集各类奇妙好玩的话题和流行动向!长按左侧图片,扫码加入架构师微信群!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值