Java 通配符通用问题:编译器为同一对象假设不同类型
我有一个与 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 ?)
是行不通的。
I have a problem related to JAVA wildcards and generics. I do not want to post my own complex code, so I will use the Collection
interface for demonstration:
Collection<String> stringCollection = new HashSet<String>();
stringCollection.add("1");
stringCollection.add("2");
stringCollection.add(stringCollection.iterator().next());
Here, the last line is no problem. add()
requires a string and next()
returns a string.
But:
Collection<?> anyCollection = stringCollection;
anyCollection.add(anyCollection.iterator().next());
Using the wildcard, Eclipse tells me the error
The method add(capture#19-of ?) in the type Collection is not applicable for the arguments (capture#20-of ?)
But why? I need to use the wildcarded Collection. Somehow Eclipse just doesn't get that next()
definitely MUST return an object exactly of the type add()
requires.
Is there any way to fix this without getting an error? For sure, a cast to (capture#20-of ?)
doesn't work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
除了
null
之外,您不能向Collection
添加任何内容。是的,您知道集合中已有的任何元素都应该能够添加到集合中,但类型并不反映这一点。和
。您能说明为什么需要使用通配符而不是
Collection
吗?(我假设您知道这一点,但在您的示例中,您的集合是一个
Set
,因此,添加其中已有的任何元素将不会执行任何操作。)编辑:
从您的评论,在我看来,您不需要通配符,而只是一个通用方法:
对于想要将
Collection
的第一个元素重新添加到其中的方法来说也是如此:具体类型参数(而不是通配符)告诉编译器从对象检索的类型与对象期望传递给其方法的类型相同。
You can't add anything but
null
to aCollection<?>
. Yes, you know that any element that's already in the collection should be able to be added to it, but the type doesn't reflect that.<?>
and<? extends Foo>
should only be used when you only need to retrieve objects from the collection and not add to it. Can you show why you need to use a wildcard as opposed to, say,Collection<E>
?(I assume you know this, but in your example your collection is a
Set
and as such, adding any element that's already in it will do nothing.)Edit:
From your comment, it sounds to me like you don't want a wildcard but just a generic method:
The same would be true of a method that wants to re-add the first element of a
Collection
to it:The specific type parameter (rather than a wildcard) tells the compiler that the type retrieved from the object is the same type that the object expects to be passed to its method.
您不能将字符串对象添加到
Collection
类型的集合中,因为 Collection 类型本身意味着您不知道集合的类型,因此编译器不允许您可以在其中添加任意类型。解决此问题的一种方法是像这样进行转换:
You can't add a string object in to a collection of type
Collection<?>
, because the type Collection itself means that you dont know the type of the collection, hence the compiler won't allow you to add arbitrary types in it.One way to fix this is to cast it like so:
制作对象的anyCollection集合
这应该可以工作
Make anyCollection collection of Object
This should work