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