Java的for循环代码是如何由编译器生成的 [英] How is Java's for loop code generated by the compiler
问题描述
<$>
如何编译生成的Java循环代码?对于(String s:getStringArray())
{
//用s
做某事}
其中 getStringArray()
是一个返回我想循环的数组的函数,被称为总是或只有一次?如何优化循环使用这个结构的代码呢?
以下是为简明起见而对 Java语言规范第三版 p>
JLS 14.14.2针对语句的增强型
增强
for
语句的格式为:
for(类型标识符:表达式)语句
如果
Expression
的类型是一个数组类型T []
,那么对于语句增强的的含义由下面的基本
for
语句:
T [] a =表达式;
语句
for(int i = 0; i< a.length; i ++){
Type Identifier = a [i];
$ / code $ / pre
其中a
和i
是编译器生成的标识符,它与任何其他标识符(编译器生成的或其他标识符)因此,实际上,该语言确实保证了for
$ / / em> 表达式
只会计算一次。 为了完整性,这里是当表达式
类型为 Iterable
:
JLS 14.14.2对于语句增强的
为$ c $增强了
c>语句的格式如下:
语句增强的
$ b $ pre $for(类型标识符:表达式)语句
如果
Express的类型ion
是Iterable
的子类型,那么让I
为表达式的类型Expression.iterator()
。对于相当于以下形式的
语句的基本:
for(I iter = Expression.iterator(); iter.hasNext();){
类型标识符= iter.next();
$ / code $ / pre
$ b $iter
是一个编译器生成的标识符,它与在增强的for
语句发生时位于范围内的任何其他标识符(编译器生成的或其他的) 。
请注意,如果 Expression
既不是编译时错误一个 Iterable
也不是一个数组,所以上面两个是唯一可以使用增强的 for
循环的情况。此外,为了清楚起见,上面的引用省略了有关循环中附加的任何标签的信息以及附加在标识符
,但这些都按照预期的方式处理。
在增强的
loop
以下是有效的Java第2版,第46项:每个循环优先于循环
在版本1.5中引入的for-each循环通过隐藏迭代器或索引来摆脱混乱和错误的机会完全可变。最终的习惯用法同样适用于集合和数组。请注意,使用for-each循环对于数组没有性能损失,甚至对于数组也是如此。事实上,在某些情况下,它可能比普通的
循环提供轻微的性能优势,因为它只计算一次数组索引的限制。虽然您可以手动完成这项工作,但程序员并不总是这样做。
因此,本书声称事实上,有些编译器超越了JLS的翻译,并在for-each循环上执行了额外的优化(当然,当然仍然保持其语义)。
总之,不要担心for-each循环的性能。由于语言的规范是明智的( How is Java's for loop code generated by the compiler? For example, if I have: where Here is the relevant excerpts from the Java Language Specification 3rd Edition, slightly edited for clarity: The enhanced If the type of where So in fact the language does guarantee that For completeness, here's the equivalence when the The enhanced If the type of where Note that it is a compile-time error if Here's a quote from Effective Java 2nd Edition, Item 46: Prefer for-each loops to traditional for loops The for-each loop, introduced in release 1.5, gets rid of the clutter and the opportunity for error by hiding the iterator or index variable completely. The resulting idiom applies equally to collections and arrays. Note that there is no performance penalty for using the for-each loop, even for arrays. In fact, it may offer a slight performance advantage over an ordinary Thus the book claims that in fact some compilers go beyond the JLS translation and performs additional optimization on the for-each loop (while still maintaining its semantics, of course). In summary, you should not worry about the performance of for-each loop. The specification by the language is sensible ( 这篇关于Java的for循环代码是如何由编译器生成的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! Expression只能被评估一次),而正是因为这是许多场景中的首选构造,所以编译器会确保
参见
for(String s : getStringArray() )
{
//do something with s
}
getStringArray()
is a function that returns the Array I want to loop on, would function be called always or only once? How optimal is the code for looping using this construct in general?On the semantics of enhanced
for
loop
JLS 14.14.2 The enhanced
for
statementfor
statement has the form:for ( Type Identifier : Expression ) Statement
Expression
is an array type, T[]
, then the meaning of the enhanced for
statement is given by the following basic for
statement:T[] a = Expression;
for (int i = 0; i < a.length; i++) {
Type Identifier = a[i];
Statement
}
a
and i
are compiler-generated identifiers that are distinct from any other identifiers (compiler-generated or otherwise) that are in scope at the point where the enhanced for
statement occurs.Expression
will only be evaluated once.Expression
is of type Iterable
:
JLS 14.14.2 The enhanced
for
statementfor
statement has the form:for ( Type Identifier : Expression ) Statement
Expression
is a subtype of Iterable
, then let I
be the type of the expression Expression.iterator()
. The enhanced for
statement is equivalent to a basic for
statement of the form:for (I iter = Expression.iterator(); iter.hasNext(); ) {
Type Identifier = iter.next();
Statement
}
iter
is a compiler-generated identifier that is distinct from any other identifiers (compiler-generated or otherwise) that are in scope at the point where the enhanced for
statement occurs.Expression
is neither an Iterable
nor an array, so the above two are the only cases where you can use an enhanced for
loop. Also, for clarity, the above quotes leave out information regarding any labels attached on the for
loop and any modifiers attached on the Identifier
, but these are handled as one would expect.
On the performance of enhanced
for
loop
for
loop in some circumstances, as it computes the limit of the array index only once. While you can do this by hand, programmers don't always do so.Expression
only evaluated once), and precisely because this is the preferred construct in many scenarios, compilers will make sure to optimize them as best they can.See also