内部类的Java类型捕获

时间:2012-11-07 01:21:04

标签: java types

我有以下(在这种形式中显然没用)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();

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

这里究竟是什么问题,是否有办法进行干净的编译?

我能做的最好的事情是:

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

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

2 个答案:

答案 0 :(得分:1)

正在尝试将entrySet分配给Set<EntrySet.Entry<SomeClass>> Set<EntrySet.Entry<?>>。有数百个Stack Overflow问题基本上是相同的。您可以为后者添加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();

答案 1 :(得分: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{}