有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么不能返回通用映射?

更新:我问了一个愚蠢的问题,我混合了B是a的子类型,然后Map<String, B>也是Map<String, A>的子类型,这显然是不正确的

公共接口A{ .... }

public class B implements A {
    ....
}

现在我有了这门课

Class abstract ABC {
    public abstract Map<String, A> execute();
}


Class XYZ {
    private ABC abc;
    public Map<String, A> doSomeWork(){
       return abc.execute()
    }
}

然后

Class DEF extends ABC {
   @Override 
   public Map<String, B> execute(){
     ....
   }
}

Class Main {

....
     XYZ xyz = new XYZ();
     DEF def = new DEF();
     xyz.setABC(def);

     Map<String, B> map = xyz.doSomeWork(); //incompatible type error here

....
}

这是我使用通用地图的方式完全错误吗?我想要的是,doSomeWork方法可以相应地返回不同类型的映射,我尝试将返回类型更改为Map<String, ? extends A>,这也不起作用

我可能无法澄清问题,我已经更新了缺失的细节


共 (2) 个答案

  1. # 1 楼答案

    假设您还有一个class C implement A

    public Map<String, A> doSomeWork()将允许您返回一个包含实现A的任何值的映射,即一组B实例以及C实例

    如果你被允许做Map<String, B> map = doSomeWork();,你会假设所有的值都是B实例,这不可能是真的,因此你会遇到一个可怕的惊喜。因为编译器不想让你感到惊讶,所以它从一开始就抱怨/警告/拒绝编译

    为什么Map<String, ? extends A> doSomeWork()不起作用?该签名将允许您返回一个Map<String, A>或一个Map<String, C>,我希望您能看到,将这两个属性分配给Map<String, B>将如何破坏您的代码

    那你能做什么

    • 假设doSomeWork()返回实现A的任何值类型的映射,只使用Map<String, A> map = doSomeWork()
    • 告诉方法它应该返回什么,例如,通过传递期望的值类型,比如doSomeWork( B.class )

    然后,该方法可以如下所示:

    public <T extends A> Map<String, T> doSomeWork( Class<T> valueType ){
       ....
    }
    
    Map<String, B> map = doSomeWork( B.class );
    Map<String, C> anotherMap = doSomeWork( C.class );
    
  2. # 2 楼答案

    如果execute的返回类型根据ABC的实现而改变,则可以将ABC设置为泛型:

    abstract class ABC<T extends A> {
        public abstract Map<String, T> execute();
    }
    
    class XYZ<T extends A> {
        private ABC<T> abc;
        public Map<String, T> doSomeWork(){
           return abc.execute();
        }
    }
    
    class DEF extends ABC<B> {
        @Override 
        public Map<String, B> execute(){
            ....
        }
    }
    

    然后:

    XYZ<B> xyz = new XYZ<>();
    DEF def = new DEF();
    xyz.setABC(def);
    
    Map<String, B> map = xyz.doSomeWork();