I am working on legacy code like below
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;
}
Obviously, I would like to adapt Generics. So I changed the method like,
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;
}
My question is about the line of recursive calls. So far, I have tried
V newElement = myMethod(value);-> Compile ErrorMap<K,V> newElement = myMethod(value);->compile ErrorV newElement = (V) myMethod((Map<?,?>)value);->Type safety warning
--------- Edited ----------
The further assumption that I could make is
- createMap() method could be changed to createMap(arg)
- Element type of arg is not bounded to a specific Java type. This is a library method so it has to be generic
valueis aMapof the right type? Then just cast to that type and ignore the warnings.Vcan be eitherStringorMap<K,V>recursing itself.Map<K, Object>would work, and you would need the cast (with the safety warning, nothing can be done against that)Map newElement = myMethod(value);becausevalueis an object, not aMap