Java foreach是否会创建副本?

时间:2015-02-05 18:51:14

标签: java foreach jvm

我对此问题有疑问:

    for(Element e : nullProof(setOfElements)){
            // do stuff
    }

假设我定义了函数nullProof来返回一个非null的Set(因为我听说你不应该将null传递给一个增强的for循环。这是真的吗?):

    private Set<Element> nullProof(Set<Element> s){
          return s == null ? Collections.<Element> emptySet() : s;
    }

我的问题是......在foreach中调用 nullProof 函数是否安全?具体来说,以下标题相当于:

    for(Element e : setOfElements){    //assuming setOfElements != null

我想知道是否有人可以指出一些Java标准,说这是定义的行为。

此外,有人可以解释实际发生的事情&#34;在幕后&#34;什么时候叫这个foreach?

我们说 setOfElements 的大小为6.对于通过 setOfElements 的每次迭代,JVM是否会查找 setOfElements 6次不同的时间,还是创建该集的副本并参考副本?我试图理解这种行为。谢谢你的帮助!

2 个答案:

答案 0 :(得分:6)

是的,这是完全安全的。

for(Element e :  nullProof(setOfElements)) {

相当于

Set<Element> s = nullProof(setOfElements);
for(Element e :  s) {

JLS-14中所述,场景背后的 ,每个循环相当于:

for(Iterator<Element> it = s.iterator() ; it.hasNext() ; ) {
    Element e = it.next();
    // ...
}

答案 1 :(得分:2)

这是安全的,因为实际的集合必须在任何迭代发生之前得到解决,但它会在某种程度上掩盖你的意图。在我看来,这更清楚:

if (setOfElements != null) {
    for (Element e : setOfElements) {
        ...
    }
}

或者,您可能希望重新评估为什么允许setOfElementsnull。首先将它作为空列表是否有意义,而不是null


  

让我们说setOfElements的大小为6.对于setOfElements的每次迭代,JVM是否会查找setOfElements 6次不同的时间,或者是否会创建该副本设置并参考副本?我试图理解这种行为。

不涉及复制。增强的for - 循环使用Iterator(由任何集合的iterator方法返回)来进行迭代。 Iterator是一个对象,它能够通过next方法逐个为您提供某些集合的元素。