我目前有三个类,并尝试实现通用访问者模式,将其放入我们所有项目共享的库中:
public interface Visitable<ReturnType> {
public ReturnType accept(Visitor<?, ?> v);
}
public interface Visitor<SomeVisitable extends Visitable<?>, ReturnType> {
public ReturnType visit(SomeVisitable v);
}
public class BaseObject implements Visitable<Void>{
public Void accept(Visitor<?, ?> v) {
v.visit(this); //1
// The method visit(capture#1-of ?) in the type
// Visitor<capture#1-of ?,capture#2-of ?> is not
// applicable for the arguments (BaseObject)
}
}
为什么我在 //1
处收到编译时错误?老实说,我真的不知道应该在该代码中重新设计什么以使其编译。
最佳答案
您的问题显然是使用通配符。您的accept
BaseObject
中的方法正在接受 Visitor<?, ?>
类型的访客.
如果你仔细想想,现在编译器必须填补 Visitor
中的空白。与这些通配符的接口(interface):
interface Visitor<? extends Visitable<?>, ?> {
? visit(? v)
}
这些被填补的空白就是所谓的通配符捕获。
现在,您尝试调用visit(this)
。编译器究竟如何知道 this
的类型?是通配符 ?
代表的实际类型?
正如 @JBNizet 所解释的,访问者背后的魔力在于它在编译时知道被访问对象的所有可能替代方案。我真的怀疑使用 Visitor<?,?>
这是一个好主意。
据我从代码示例中可以看出,问题的解决方案在于在访问者声明中使用实际类型参数而不是通配符。
关于java - Java中通配符捕获,无法调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30002185/