为什么我不能返回通用地图?

Nee*_*n.Z 0 java generics interface

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

公共接口A {....}

public class B implements A {
    ....
}
Run Code Online (Sandbox Code Playgroud)

现在我有这门课.

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


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

然后

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

....
}
Run Code Online (Sandbox Code Playgroud)

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

我可能没有澄清问题,我已经更新了遗漏的细节.

Tho*_*mas 5

假设你有一个额外的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 );
Run Code Online (Sandbox Code Playgroud)