2015-05-02 108 views
2

我目前有三类,并试图实现通用Visitor模式以便让你可以到我们的所有项目中共享库:通配符捕获在Java中,无法调用的方法

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?老实说,我真的不知道我应该重新编写代码来编译它。

+4

这没有多大意义。为了有用,Visitor接口应该为每个BaseObject子类使用一个visit()方法。所以它不应该是通用的。 –

+0

你试过吗?扩展BaseObject'? –

+0

@JBNizet你的意思是访问者的实现不应该是通用的,是吧?如果是这样,让我不同意你的看法,因为如果我们把所有这些员工放在一个库中,我们会编写更具可读性和简单的代码,并避免创建这些样板类。这不好吗? – user3663882

回答

2

你的问题显然是使用通配符。您在BaseObject中的accept方法正在接受Visitor<?, ?>类型的访问者。

如果你想想看,现在的编译器,以填补在Visitor接口与这些通配符的差距:填充

interface Visitor<? extends Visitable<?>, ?> { 
    ? visit(? v) 
} 

这些差距是,所谓的通配符捕获。

现在,您尝试调用visit(this)。编译器如何知道this的类型是否是由通配符?表示的实际类型?

正如@JBNizet所解释的那样,访问者背后的神奇之处在于,它在编译时知道所访问对象的所有可能替代方案。我真的怀疑在这里使用Visitor<?,?>是个好主意。

您的问题的解决方案在于使用实际的类型参数,而不是您的访客声明中的通配符,只要我可以从您的代码示例中知道。

相关问题