[英]How to call generic method of wildcard type in Java?
我发现我不能调用通配符类型的泛型方法而且不明白为什么?
public class GenericsTry2 {
public static class Element {
private Container<? extends Element> container;
public Container<? extends Element> getContainer() {
return container;
}
public void setContainer(Container<? extends Element> container) {
this.container = container;
}
public void doStuff() {
getContainer().doStuff(this); // how to call this?
}
}
public static class SomeSubElement extends Element {
}
public static class SomeSubElement2 extends Element {
}
public static class Container<E extends Element> {
public void doStuff(E element) {
}
}
public static void main(String[] args) {
Container<SomeSubElement2> c = new Container<SomeSubElement2>();
Element e = new SomeSubElement();
c.doStuff((SomeSubElement2) e); // still can do this at compile time this way
}
}
有Container<? extends Element>
Container<? extends Element>
表示Container
只能生成 Element
,但不能使用 Element
。
原因是这个? extends Element
? extends Element
表示一系列未知的Element
子类型。 我们假设您将容器设置为Container<SomeSubElement>
。 然后,通过this
在容器(即使你知道这是一个Element
,或子类的Element
)将不会是正确的,因为this
可能会或可能不会SomeSubElement
(取决于运行时类型)。
在泛型世界中,这被称为协方差。
为了编译代码(我不保证你需要这个),你可以这样做(注意我已经将容器改为Element
(s)的使用者而不是生产者):
public class Element {
private Container<? super Element> container;
public Container<? super Element> getContainer() {
return container;
}
public void setContainer(Container<? super Element> container) {
this.container = container;
}
public void doStuff() {
getContainer().doStuff(this);
}
}
但是,如果您需要同时将Container
作为生产者和消费者,只需删除通配符并仅使用<Element>
对其进行参数化。
Container<E extends Element>
意味着它包含从Element
扩展的东西E
不一定是Element
本身。
想象一下如果你有以下会发生什么:
Container<RedElement> redElements = new Container<RedElement>();
Container<E extends Element> container = redElements;
// According to your logic it will work
container.add(new Element());
// Problem here. You just put Element there which is not RedElement.
RedElement element = container.getFirst();
getContainer()
方法保证返回扩展Element的类的某个对象。 因此编译器此时不知道返回的值实际上是Container
类型。 如果要调用Container
类的doStuff()
Method,则必须将getContainer()
的结果显式转换为Container
类型。
((Container) getContainer()).doStuff(this);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.