java - Java中通配符捕获,无法调用方法

标签 java generics design-patterns wildcard

我目前有三个类,并尝试实现通用访问者模式,将其放入我们所有项目共享的库中:

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/

相关文章:

Java newColor 构造函数随机化

java - 如何按列对二维整数数组进行排序

java - 阻止用户在计算器中使用某些字符

Java Generics Silly Thing(为什么我不能推断类型?)

c# - 在此示例中如何避免破坏 LSP? C#

javascript - 使用 Java 从 Alfresco for Selenium WebDriver 的动态制作导航中获取所有元素

java - 如何将 Java Stream 转换为 Scala 数组?

swift - 将数据传递给接受通用集合的函数

java - 如何在 Android 中管理可运行任务队列

c# - 我应该在工厂模式类中处理异常还是让它们向上传播?