1

我有以下(在这种形式下显然没用)Java类:

public class EntrySet<T> {

    public static class Entry<T> {
        T obj;
    }

    private final Set<Entry<T>> set;

    public EntrySet() {
        this.set = Sets.newHashSet();
    }

    public Set<Entry<T>> getEntries() {
        return set;
    }
}

鉴于此类,以下内容无法编译:

EntrySet<?> entrySet = new EntrySet<SomeClass>();
Set<EntrySet.Entry<?>> entries = entrySet.getEntries();

第二行有编译错误“cannot convert from Set<EntrySet.Entry<capture#1-of ?>>to Set<EntrySet.Entry<?>>”。即使使用强制转换或使用辅助函数,我也找不到消除此错误的方法。

这里到底是什么问题,有没有办法获得干净的编译?

我能做的最好的是:

EntrySet<?> entrySet = new EntrySet<SomeClass>();
Set<?> tmp = entrySet.getEntries();
Set<EntrySet.Entry<?>> entries = (Set<EntrySet.Entry<?>>) tmp;

这显然很糟糕(即使有相关的警告抑制)。

4

2 回答 2

1

删除entrySet您正在尝试将 a 分配Set<EntrySet.Entry<SomeClass>>Set<EntrySet.Entry<?>>。有数百个 Stack Overflow 问题本质上是相同的。您可以将 a 添加EntrySet.Entry<OtherClass>到后者但不能添加到前者,这样会破坏类型安全。

处理这个问题的方法可能是通过调用带有(命名的)泛型参数的方法来捕获通配符。

    EntrySet<?> entrySet = new EntrySet<SomeClass>();
    fn(entrySet);
...
private static <T> void fn(EntrySet<T> entrySet) {
    Set<EntrySet.Entry<T>> entries = entrySet.getEntries();
于 2012-11-07T01:33:02.203 回答
0

无界通配符<?>就像所有泛型类型的超类型。它类似于 Object 类对所有 java 类的作用。您可以对无界通配符引用执行的唯一操作是那些采用“null”(如果<?>在参数引用中使用参数)或返回“Object”(如果<?>在返回类型引用中使用参数)的操作。因此,如果它返回 Object 类型的引用,您的代码将编译。

 class EntrySet<T> {

    public static class Entry<T> {
        T obj;
    }

    private final java.util.Set<Entry<T>> set;

    public EntrySet() {
        this.set = new java.util.HashSet();
    }

    public java.util.Set<Entry<T>> getEntries() {
        return set;
    }

    public static void main(String [] args){
        EntrySet<?> entrySet = new EntrySet<SomeClass>();

    //java.util.Set<EntrySet.Entry<?>> entries = entrySet.getEntries(); // Error

         Object o = entrySet.getEntries();         // OK !
    }
}

class SomeClass{}
于 2012-11-07T02:28:23.567 回答