【问题标题】:Error while adding items to a list with a wildcard使用通配符将项目添加到列表时出错
【发布时间】:2015-04-14 19:58:31
【问题描述】:
private static Map<String, List<?>> eventsMap = new HashMap<>();

public static void logEvent(String eventIdentifier, Class<?> event) {
    if (!eventsMap.containsKey(eventIdentifier)) {
        eventsMap.put(eventIdentifier, new ArrayList<>());
    }
    eventsMap.get(eventIdentifier).add(event);
}

我正在尝试创建一个可以记录事件的日志类。为此,我使用了一个将标识符链接到事件列表的 Map。我希望能够将任何类型的对象放入列表中,但是一旦确定了列表的类型,添加到列表中的所有下一个项目都必须符合第一种类型。例如:

    LogWriter.logEvent("date", "0:00:01");
    LogWriter.logEvent("date", "0:00:02");
    LogWriter.logEvent("date", "0:00:03");

    String[] a = {"street", "zipcode", "housenumber", "city"};
    String[] b = {"street", "zipcode", "housenumber", "city"};
    String[] c = {"street", "zipcode", "housenumber", "city"};

    LogWriter.logEvent("address", a);
    LogWriter.logEvent("address", b);
    LogWriter.logEvent("address", c);

但是我得到一个编译错误

eventsMap.get(eventIdentifier).add(event);

no suitable method found for add(Class<CAP#1>)
    method Collection.add(CAP#2) is not applicable
      (argument mismatch; Class<CAP#1> cannot be converted to CAP#2)
    method List.add(CAP#2) is not applicable
      (argument mismatch; Class<CAP#1> cannot be converted to CAP#2)
  where CAP#1,CAP#2 are fresh type-variables:
    CAP#1 extends Object from capture of ?
    CAP#2 extends Object from capture of ?

请解释为什么以及如何解决这个问题。

【问题讨论】:

标签: java list generics compiler-errors wildcard


【解决方案1】:

eventsMap 的声明中有一个通配符:

private static Map<String, List<?>> eventsMap = new HashMap<>();

这意味着在您的地图中存储为值的Lists 可以是任何内容的列表。但这并不意味着任何东西都可以存储在其中。它是一个特定但未知类型的列表。它可以是List&lt;Object&gt;List&lt;Integer&gt;List&lt;Foo&gt;。出于类型安全原因,编译器必须禁止对add 的此类调用,因为它无法判断event 是否属于正确的类型。

因为event 似乎是Class,所以将通配符替换为Class&lt;?&gt;

private static Map<String, List<Class<?>>> eventsMap = new HashMap<>();

这样,代表任何类的Class 对象可以插入到从您的地图检索到的列表中。

【讨论】:

  • 感谢您的快速回复!我不想在列表中插入“类”对象,我试图找到一种将“事件”放入列表的方法。 “事件”通常是“列表”或“字符串”对象。至少现在我知道 'Class> event' 作为方法参数不起作用,谢谢!
  • 您将event 的类型指定为Class&lt;?&gt;。无论如何,如果eventFoo,那么Map 的类型应该是Map&lt;String, List&lt;Foo&gt;&gt;
猜你喜欢
  • 2014-03-13
  • 1970-01-01
  • 2013-09-03
  • 1970-01-01
  • 2017-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多