2012-11-07 48 views
1

我有以下的(这种形式显然是无用)的Java类: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; 

这显然是可怕的(即使有相关的警告抑制)。

+0

您是否尝试过EntrySet entrySet = new EntrySet (); ? – Jerome

+0

这只是一些虚拟代码,以确保问题清楚。这当然会起作用,但就我而言,我所拥有的只是一个'EntrySet '。 – Carl

回答

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(); 
+0

不能添加'EntrySet.Entry ''来设置>'。你不能添加*任何*到它。 –

+0

我不确定我是否按照这个问题行事。正如@MiserableVariable所说的,你不能插入一个'Set >'。例如,编写'Map map = new HashMap ();'后面跟着'Set keys = map.keySet();'完全可以。关于通配符嵌套的事实是有所不同的,虽然它肯定有点像你说的,但我没有看到它。 – Carl

+0

我相信你可以添加到'Set >'(没有得到安装在这台机器上的Java来检查)。 /我想'入口'声明为'设置<?扩展EntrySet.Entry >'也将工作(对于某些目的)。 –

0

无界通配符<?>就像所有泛型类型的超类型。它与所有Java类的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{}