Java中泛型方法的递归调用

Java中泛型方法的递归调用,java,generics,recursion,Java,Generics,Recursion,我正在处理下面这样的遗留代码 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.n

我正在处理下面这样的遗留代码

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;
}
publicmap-myMethod(Map-arg){
Map newMap=createMap();//创建一个新的映射实例。
for(条目:arg.entrySet()){
K key=entry.getKey();
V value=entry.getValue();
if(映射的值实例){
V newElement=myMethod(value);//此处递归调用
newMap.put(键,新元素);
}else if(字符串的值实例){
newMap.put(键、值);
}
}
返回newMap;
}
我的问题是关于递归调用的行。到目前为止,我已经试过了

  • V newElement=myMethod(值)->编译错误
  • Map newElement=myMethod(值)->编译错误
  • V newElement=(V)myMethod((Map)值)->类型安全警告
  • ---------编辑----------

    我可以做的进一步假设是

  • createMap()方法可以更改为createMap(arg)
  • arg的元素类型未绑定到特定的Java类型。这是一个库方法,因此它必须是泛型的

  • 你的类型都搞砸了

    你的方法需要一段时间

    Map<K,V> 
    
    一定是

    Map<K,V> newElement = myMethod(element);  //element is of type Map<K,V>
    
    意味着新元素也必须是V类型

    所以你基本上需要String,Map和V来拥有一些通用的超类型。在原始代码中,Map实际上是

    Map<Object, Object>
    
    Map
    
    所以超类型是Object

    我会备份,并问自己为什么有一个同时存储地图和字符串的地图。您可能应该将它们重构为实际表示其类型的对象

    例如,假设它是一个文件系统,映射是一个目录,字符串是一个文件,那么您应该真正创建一个FileObject,它可以是目录或文件,并且您的方法签名变成:

    Map<K, FileObject> myMethod(Map<K, FileObject> map)
    
    Map-myMethod(Map-Map)
    
    代码的逻辑不是类型安全的,因此无法避免类型安全警告

    您可以使用
    createMap()
    创建一个新映射;该方法盲目地创建一个没有信息的新映射,因此它创建的映射类不一定与传入的
    arg
    类相同。这意味着您的方法
    myMethod()
    返回的映射不一定与传入的映射属于同一个实现类


    在递归调用中,您将一个我们知道是
    V
    实例的映射传递到递归调用中,您希望返回的对象是
    V
    。但这不一定是真的。例如,如果
    V
    TreeMap
    ,递归调用返回的东西是
    HashMap
    ,该怎么办?那么它应该不能转换为
    V
    ,并且您无法从中安全地获得
    V

    您确定
    是正确类型的
    映射吗?然后转换为该类型并忽略警告。问题是
    V
    可以是
    String
    Map
    本身递归<代码>映射将起作用,并且您将需要强制转换(带有安全警告,无法针对该警告执行任何操作)旁注:您的旧代码不在此处编译:
    映射新元素=myMethod(值)因为
    是一个对象,而不是
    映射
    @njzk2 I编辑。谢谢。因为这个方法被其他应用程序使用(超过100次调用这个方法),而且它是一种库方法,所以我不能改变异构元素的性质。这实际上是原始方法的简化版本。参数映射将整数、列表、双精度、映射作为元素。那么泛型在这里就帮不了你。您需要强制转换,它将被取消选中并发出警告。编译器无法事先知道V是否真的是正确的类型。有意义。假设我将createMap()更改为createMap(arg),它返回给定参数的新实例,那么该方法是否是类型安全的,并且我可以强制使用泛型?@exiter2000:这样会更安全。但是,即使您更改了方法的签名,我也不确定您是否可以避免未经检查的强制转换。
    newMap.put(key, newElement);
    
    Map<Object, Object>
    
    Map<K, FileObject> myMethod(Map<K, FileObject> map)