繁体   English   中英

Java通配符通用问题:编译器为同一对象假定不同的类型

[英]Java wildcard generic problem: Compiler assumes different types for same object

我有一个与JAVA通配符和泛型有关的问题。 我不想发布自己的复杂代码,因此我将使用Collection接口进行演示:

Collection<String> stringCollection = new HashSet<String>();
stringCollection.add("1");
stringCollection.add("2");
stringCollection.add(stringCollection.iterator().next());

在这里,最后一行没问题。 add()需要一个字符串, next()返回一个字符串。

但:

Collection<?> anyCollection = stringCollection;
anyCollection.add(anyCollection.iterator().next());

Eclipse使用通配符告诉我错误

Collection类型中的方法add(capture#19-of?)不适用于参数(capture#20-of?)

但为什么? 我需要使用通配符集合。 Eclipse以某种方式无法获得next()绝对必须返回类型完全为add()所需的对象。

有什么办法可以解决这个问题而不会出错? 当然,强制转换为(capture#20-of ?)无效。

您只能将null添加到Collection<?> 是的,您知道应该已经可以将集合中已经存在的任何元素添加到其中,但是类型不能反映这一点。 <?><? extends Foo> 仅当您只需要从集合中检索对象而不添加到集合中时,才应使用<? extends Foo> 您能说明为什么需要使用通配符而不是Collection<E>吗?

(我假设您知道这一点,但是在您的示例中,您的集合是Set ,因此,添加其中已经存在的任何元素都将无济于事。)

编辑:

根据您的评论,在我看来,您不需要通配符,而只是一个通用方法:

public <T extends PersistenceObject> void doSomething(Dao<T> dao) {
  T o = dao.createNew();
  // ...
  dao.save(o);
}

想要向其重新添加Collection的第一个元素的方法也是如此:

public <E> boolean reAddFirst(Collection<E> collection) {
  return collection.add(collection.iterator().next());
}

特定的类型参数(而不是通配符)告诉编译器从对象检索的类型与该对象期望传递给其方法的类型相同。

您不能在类型Collection<?>的集合中添加字符串对象,因为类型Collection本身意味着您不知道集合的类型,因此编译器不允许您在其中添加任意类型。

解决此问题的一种方法是像这样进行投射:

    Collection<?> c = new HashSet<String>();
    Collection strCol = (Collection<String>)c;
    strCol.add("Suraj");

制作对象的anyCollection集合

Collection<Object> anyCollection = stringCollection;

这应该工作

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM