使用 Iterables、Maps、Objects 和?

Argument conversion with Iterables, Maps, Objects and?

我有一个类型的变量:

Iterable<Map<String,Object>>

我正在尝试 return 它的类型:

Iterable<Map<String,?>>

编译器说:

argument mismatch; Iterable<Map<String,Object>>
cannot be converted to Iterable<Map<String,?>>

有人知道如何在此处强制编译器进入 "doing the right thing",或者这在某种程度上是不可能的?

您始终可以转换为无类型的 Iterable 并让 return 语句执行未经检查的转换回您想要的类型:

public static Iterable<Map<String, ?>> getIt() {
    Iterable<Map<String, Object>> t = null;
    return ((Iterable) t);
}

如果您不想使用仅转换为原始类型的大棒方法(这可能会导致麻烦 - 请参阅 What is a raw type and why shouldn't we use it?),您始终可以使用根本不需要转换的瘦适配器,从而维护所有可能的类型安全:

// Could probably be done inline with a little tweaking.
class IMSQ implements Iterable<Map<String, ?>> {

    // The adaptee.
    final Iterable<Map<String, Object>> o;

    public IMSQ(Iterable<Map<String, Object>> o) {
        this.o = o;
    }

    @Override
    public Iterator<Map<String, ?>> iterator() {
        // Pull a new Iterator out of it.
        final Iterator<Map<String, Object>> it = o.iterator();
        // Wrap it.
        return new Iterator<Map<String, ?>>() {

            @Override
            public boolean hasNext() {
                return it.hasNext();
            }

            @Override
            public Map<String, ?> next() {
                return it.next();
            }

        };
    }

}

Iterable<T> 应该是 Iterator<T> 的 "Producer",它又是其类型参数 T 的 "Producer"(只有一个方法returns T,并且没有采用 T 的方法)。因此,根据PECS(Producer extends, Consumer super)规则,它应该始终与extends通配符一起使用。

如果你有一个

类型的变量
Iterable<? extends Map<String,Object>>

而你return它是

Iterable<? extends Map<String,?>>

没有问题。每当你从中得到 Iterator 时,你将类似地键入它作为 Iterator<? extends Something>.