[英]Recursive call with Generic method in Java
我正在處理如下的舊代碼
public Map myMethod(Map arg){
Map newMap = createMap(); //This method creates a new Map instance.
Iterator entries = arg.entrySet().iterator();
while (entries.hasNext()) {
Entry thisEntry = (Entry) entries.next();
Object key = thisEntry.getKey();
Object value = thisEntry.getValue();
if ( value instanceof Map){
Map newElement = myMethod((Map)value); // Recursive call here
newMap.put(key, newElement);
}else if ( value instanceof String ){
newMap.put(key, value);
}
}
return newMap;
}
顯然,我想改編泛型。 所以我改變了方法,
public <K,V> Map<K,V> myMethod(Map<K,V> arg){
Map<K,V> newMap = createMap(); //creates a new Map instance.
for ( Entry<K,V> entry : arg.entrySet()){
K key = entry.getKey();
V value = entry.getValue();
if ( value instanceof Map){
V newElement = myMethod(value); // Recursive call here
newMap.put(key, newElement);
}else if ( value instanceof String ){
newMap.put(key, value);
}
}
return newMap;
}
我的問題是關於遞歸調用的行。 到目前為止,我已經嘗試過
V newElement = myMethod(value);
->編譯錯誤 Map<K,V> newElement = myMethod(value);
->編譯錯誤 V newElement = (V) myMethod((Map<?,?>)value);
->輸入安全警告 ---------編輯----------
我可以做的進一步假設是
代碼的邏輯不是類型安全的,因此無法避免類型安全警告。
您可以使用createMap()
創建一個新地圖; 該方法正在盲目創建新地圖,沒有任何信息,因此它創建的地圖類不必與傳入的arg
類相同。這意味着您的方法myMethod()
返回的地圖不一定是與傳入的類相同的實現類。
在遞歸調用中,您將一個我們知道是V
的實例的映射傳遞到遞歸調用中,並且您希望返回的對象是V
但這不一定是正確的。 例如,如果V
是TreeMap
,而遞歸調用返回的是HashMap
呢? 這樣它就不能轉換為V
,並且您不可能從中安全地獲得V
您的類型都在這里弄亂了。
您的方法需要
Map<K,V>
並返回一個
Map<K,V>
那意味着電話
V newElement = myMethod(element);
一定是
Map<K,V> newElement = myMethod(element); //element is of type Map<K,V>
和電話
newMap.put(key, newElement);
表示newElement也必須為V類型。
因此,您基本上都需要String,Map和V來具有某種通用的超級類型。 在原始代碼中,Map實際上是
Map<Object, Object>
所以超級類型是Object。
我會備份並問自己,為什么您有一個同時存儲Maps和Strings的映射。 您可能應該將它們重構為實際代表其類型的對象。
例如,假設它是一個文件系統,而Map是一個目錄,而String是一個文件,那么您實際上應該創建一個既可以是目錄也可以是文件的FileObject,並且您的方法簽名變為:
Map<K, FileObject> myMethod(Map<K, FileObject> map)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.