簡體   English   中英

Java:對於每個循環,迭代擴展對象

[英]Java: For each loop , Iteration over extended objects

我的問題可能很簡單,

我有一個帶有一些內部字段,setter和getter的類Result

另外,我有一個類Special1Result ,它擴展了Result並包含了更多的字段和Special2Result以及更多的數據。

在不同的Dispatcher類中,我編寫了以下方法:

processResults(List<? extends Result> results) ,它只熟悉Result (我需要這個方法來查詢擴展Result對象中是否有特定字段 - 我正在使用注釋)。

所以我決定使用擴展for-each循環: for (Result res : results) {}

那么我的問題是什么? 我試圖通過網絡找到如何為擴展對象寫這個for循環,例如這樣的東西for (? extends Results res: results){}

可能嗎? 寫它的正確方法怎么樣?

你對List<? extends Result>所有了解List<? extends Result> List<? extends Result>是每個元素都是一個Result - 所以你可以放入增強的for循環語法。

如果您需要未在Result聲明的成員,則需要在循環內部進行強制轉換:

for (Result result : results) {
    if (result instanceof CleverResult) {
        CleverResult clever = (CleverResult) result;
        // Use clever here
    }
}

想想如果你沒有使用增強的for循環你會寫什么 - 你還需要寫演員,不是嗎?

當然,如果您知道列表實際上只包含一個特定類型,則始終可以無條件地在循環中進行轉換。

我試圖通過網絡找到如何為擴展對象編寫這個for循環,例如像這樣的東西

for (? extends Results res: results){}

不,這是不可能的:您無法靜態鍵入在運行時動態提供的項目。

寫它的正確方法怎么樣?

你已經這樣做了:

for (Results res: results) {
}

如果您想在該循環中測試Special2Result ,您可以這樣做,但通常它會告訴您的設計可以改進。 更好的選擇是使用雙重調度機制(例如訪問者模式 )來隱藏子類的特殊處理細節。

Java具有類型擦除 - 集合的具體類型參數在運行時不存在。

因此,如果您有一個List,那么java編譯器將確保沒有代碼將任何內容放入不屬於Result子類的列表中。

因此,在運行時,您的所有循環都可以知道內容是Result的所有子類 - 因此循環它們的唯一方法是作為Result的一組引用,具有任何子類的結果所呈現的任何多態行為在列表中。

由於您的具體子類僅因字段的性質而不同,我建議您從簡單的多態性中受益。

您最終將得到一個Result接口/抽象類,它定義一個execute()方法類,該類由您需要包含自己要執行的操作的多個類或子類實現。

因此,您的客戶端代碼只能使用:

for (Result res : results){    //results being as a List<Result> type
  res.execute(); 
}

暫無
暫無

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

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