foreach表达式右侧是否会每次循环重算?性能影响探讨
关于foreach循环中集合方法调用的性能疑问解答
首先明确结论:绝大多数业务场景下,两种写法的性能没有任何区别。
Java的foreach是语法糖,编译后会被转换成基于迭代器的循环逻辑。不管你是直接把otherFoo.getFoos()写在foreach括号里,还是先把集合存到变量再循环,编译后的字节码本质上是一样的——都是先调用一次getFoos()获取集合对象,然后拿到它的迭代器进行遍历,不会在每次循环迭代时重复调用getFoos()。
举个编译后的等价代码例子,两种写法最终都会变成类似这样:
Iterable<Foo> temp = otherFoo.getFoos(); Iterator<Foo> iterator = temp.iterator(); while (iterator.hasNext()) { Foo foo = iterator.next(); // 你的循环体逻辑 }
那什么时候会有差异?只有当getFoos()方法本身存在特殊逻辑时:
- 如果
getFoos()每次调用都会生成新的集合对象(比如每次都new一个List返回),或者内部包含复杂计算、IO操作,那直接写在foreach里确实会额外消耗资源——但这本质是方法本身的问题,不是foreach的写法导致的,而且这种情况下遍历逻辑也会出错(每次循环都遍历新集合)。 - 如果
getFoos()只是简单返回类的成员变量(比如return this.foos;),那两种写法完全等价。
你的同事的说法大概率是基于老旧认知或者对foreach编译逻辑的误解,现代Java编译器(Java 5及以上,foreach从Java5开始引入)都会自动做这个优化,没必要为了所谓的性能刻意把集合提前存到变量里。
内容的提问来源于stack exchange,提问作者Zack Macomber
相关产品推荐
相关产品推荐

