Java的每个vs常规 – 是等效的?

这两个结构是否相当?

char[] arr = new char[5];
for (char x : arr) {
    // code goes here
}

相比:

char[] arr = new char[5];
for (int i = 0; i < arr.length; i++) {
    char x = arr[i];
    // code goes here
}

也就是说,如果我将正确的代码放在两个循环的正文中(他们编译),它们的行为是否完全相同?

完全免责声明:这是另一个问题(Java: are these 2 codes the same)的启发。我的答案不是答案,但我觉得Java的确切语义每个都有一些需要指出的细微差别。

虽然这两种结构通常是可互换的,但它们不是100%等价的!

可以通过定义//代码到这里来构建一个证明,这将导致两个结构的行为不同。一个这样的环体是:

arr = null;

因此,我们正在比较:

char[] arr = new char[5];
for (char x : arr) {
    arr = null;
}

有:

char[] arr = new char[5];
for (int i = 0; i < arr.length; i++) {
    char x = arr[i];
    arr = null;
}

两个代码编译,但如果运行它们,您会发现第一个循环正常终止,而第二个循环将抛出NullPointerException。

这意味着它们不是100%的等价物!有两种情况下两种结构的行为会有所不同!

这种情况可能很少见,但是在调试时不应该忘记这个事实,因为否则你可能会错过一些非常微妙的错误。

作为增编,请注意,有时候for-each结构甚至不是一个选项,例如如果你需要索引。这里的关键教训是,即使这是一个选择,您需要确保它实际上是一个等同的替代品,因为它并不总是保证

同样的,如果你开始一个for-each循环,后来意识到你需要切换到索引for循环,请确保你保留语义,因为它不能保证。

特别是,对于对数组/集合的引用进行任何修改,都要被iterated_(修改内容可能/可能不会触发ConcurrentModificationException,但这是一个不同的问题)。

当使用使用自定义迭代器的集合时,保证语义保存也更加困难,但是如该示例所示,即使涉及简单数组,两个结构也是不同的。

http://stackoverflow.com/questions/2422690/java-for-each-vs-regular-for-are-they-equivalent

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:Java的每个vs常规 – 是等效的?