簡體   English   中英

Java foreach聲明中的字段賦值

[英]Field assignment in a Java foreach declaration

我知道以下示例中使用的foreach循環無法編譯。 但有人知道為什么不允許在foreach循環聲明中使用字段?

public class Foo {
    private Object obj;

    public void run(List<Object> objects) {
        for (obj : objects) {
            process();
        }
    }

    private void process() {
        // do something with obj
    }
}

可能是因為它

  • 限制循環變量的范圍(從而使代碼更清晰,並避免可能的細微錯誤),以及
  • 簡化了編譯器的解析。

分配給foreach循環中的字段通常沒有意義。 foreach循環中對象的范圍只是循環的一次迭代,而字段的范圍是對象的生命周期。

你應該把每個對象作為參數傳遞給process() ......你不會通過將引用存儲為字段來獲得任何東西。 另外,如果你真的想要,你可以使用this.obj = obj手動分配到一個字段。

我希望有幾個原因,但它可能只是為了防止程序員錯誤。

令人困惑的一件事是“循環執行后obj的價值是什么”? 與標准for循環不同,增強的for-each循環並不試圖保證自己的機制。

另一件事是實例字段代表對象的狀態。 通過在for-each循環中使用實例字段,您要說的是對象可以從一個狀態更改為一個或多個中間狀態,然后在單個操作過程中更改為最終狀態。 這只是糟糕的設計,值得預防。

為什么不將obj作為參數傳遞給process()

運行for循環之前obj應該有什么值,循環運行后應該有什么值? 這會令人困惑。

2004年有一個關於這個問題的錯誤報告 。它被拒絕了,回復很有意思:

通過強制循環變量在循環內聲明,采用了某種“安全優先”的方法(參見JLS 14.14.2中的翻譯)。 首先,不存在意外地破壞封閉范圍中的變量的危險。 其次,如果變量由循環體傳遞給其他線程,則每次迭代使用一個新的循環變量可以避免並發問題。 第三,編譯器可以通過將循環變量聲明為“final”來進行優化。 第四,如果封閉范圍中的變量被重用作循環變量,並且程序員認為循環遍歷整個集合,那么他們可能期望能夠在迭代之后通過循環觀察集合中的最后一個元素變量。 但它不一定會引用最后一個元素,例如,如果循環中斷了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM