【问题标题】:Can't create generic for an interface implementor无法为接口实现者创建泛型
【发布时间】:2014-08-08 23:22:10
【问题描述】:

我正在尝试创建一种服务定位器类,其中有一个

Map<Integer, ? extends ISomething>

但我以后不能这样做

myMap.put(0x00, new SomethingImplementor())

当我收到Error:(18, 33) java: incompatible types: org.sample.SomethingImplementor cannot be converted to capture#1 of ? extends ISomething

我的班级结构如下:

public interface ISomething {
    public void doSomething();
}

public class SomethingImplementor implements ISomething {
    @Override public void doSomething() {...}
}

为什么我不能创建这个地图并将值放入其中?

【问题讨论】:

    标签: java oop generics map compiler-errors


    【解决方案1】:

    您根本不需要通配符。

    可以直接使用

    Map<Integer, ISomething>
    

    你可以实现ISomething的每个子类。

    无论如何,在这种情况下,要使用通配符,您应该使用super。使用extends,您不知道它将是什么类型,因此您无法向地图添加任何内容。

    List 是有界通配符的一个示例。这 ?代表未知类型,就像我们之前看到的通配符一样。但是,在这种情况下,我们知道这种未知类型实际上是 Shape 的子类型。 (注意:它可以是 Shape 本身,也可以是某个子类;它不需要从字面上扩展 Shape。)我们说 Shape 是通配符的上限。

    像往常一样,使用通配符的灵活性需要付出一些代价。这个代价是现在在方法体中写入形状是非法的。例如,这是不允许的:

    您应该能够弄清楚为什么不允许上面的代码。 shape.add() 的第二个参数的类型是 ?扩展 Shape——Shape 的未知子类型。由于我们不知道它是什么类型,所以我们不知道它是否是 Rectangle 的超类型;它可能是也可能不是这样的超类型,因此在此处传递 Rectangle 是不安全的。

    通配符:http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html

    【讨论】:

      【解决方案2】:

      不要使用未知类型?

      Map<Integer, ISomething> map;
      

      使用未知类型不会获得任何好处,只需指定ISomething 就足够了,而且是正确的选择。

      此外,泛型类型必须完全匹配;即? extends ISomethingISomething不是同一个类型

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多