【问题标题】:Problem using generic map with wildcard使用带有通配符的通用映射的问题
【发布时间】:2010-12-27 15:11:57
【问题描述】:

我有一个返回 map 的方法,定义为:

public Map<String, ?> getData();

这个方法的实际实现我不清楚,但是,当我尝试这样做时:

obj.getData().put("key","value")

我收到以下编译时错误消息:

方法 put(String, capture#9-of ?) 在类型地图 不适用于论点 (字符串,字符串)

有什么问题? String 不是什么类型的吗?

提前致谢。

【问题讨论】:

  • 感谢您的回答。我对您的反应速度印象深刻...非常感谢

标签: java generics map arguments wildcard


【解决方案1】:

返回类型

Map<String, ?>

相同
Map<String, ? extends Object>

表示返回的具体类型可以是Map&lt;String, AnyClass&gt;。您不能将String 放入AnyClass,因此会出现错误。

一个好的一般原则是不要在方法返回类型中使用通配符。

【讨论】:

    【解决方案2】:

    通配符的意思是“值类型参数可以是任何东西”——它的意思是“你可以使用它,就好像它是你想要的任何东西一样”。换句话说,Map&lt;String, UUID&gt;Map&lt;String, ?&gt; 一样有效 - 但您不希望能够将字符串值放入其中。

    如果你想要一个绝对可以接受字符串值的地图,你想要:

    Map<String, ? super String>
    

    【讨论】:

    • String 类是最终的,所以只是 Map
    • @nybon 假设您有 A 类扩展 Map 和 B 类扩展 Map,您想编写一个可以将 A 类或 B 类作为参数的方法.那是你需要 Map
    【解决方案3】:

    Map&lt;String, ?&gt;Map&lt;String,? extends Object&gt; 的缩写形式,并不意味着任何东西都可以作为价值添加。它表示 Map-object 可以具有任何扩展 Object 的通用值类型。

    这意味着 Map 对象也可以是 HashMap&lt;String, String&gt;HashMap&lt;String, Integer&gt;。因为编译器无法检查哪些值类型会被接受,所以他不会让你调用以值类型作为参数的方法。

    注意:

    • 你可以调用带有值类型作为返回值的方法,因为一切都必须扩展 Object (? extends Object)
    • Map&lt;String, ? super String&gt; 会产生相反的效果:您始终可以使用字符串作为参数,但返回类型不明确。

    【讨论】:

      【解决方案4】:

      试试这个:

      public Map<String, Object> getData();
      

      【讨论】:

        【解决方案5】:

        [编辑]这真的错了……我明白了。

        我的第一个答案是:

        那是 java : String 不是对象。

        试试

        obj.getData().put("key",new String("value"));
        

        但是 String 扩展了 Object... 而我认为 String 是原始的。我学到了一些东西^^

        【讨论】:

        • 一个字符串肯定一个对象。您认为在这种情况下显式调用 String 构造函数会有什么确切的区别?
        • String 不是原始类型,是吗?
        • 不,它不是原始类型……那你为什么声称它不是对象?
        • 我相信它是一个原始的,就像一个几乎是物体......错了!但是我的想法和本灵的想法有什么区别?
        • Ben Lings 的回答完全不同,而且准确。您认为您的答案与 Ben 的相似之处在哪里?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-13
        • 1970-01-01
        • 2020-04-30
        • 2017-12-31
        • 1970-01-01
        • 2018-11-03
        相关资源
        最近更新 更多