一般类型的访问者被错误类型调用

时间:2019-06-23 19:50:58

标签: java generics polymorphism visitor

我使用的是框架AbstractProcessor<T extends CtElement>的通用抽象类,基本上是访问所有元素T的访问者。有一种方法

public void process(T element)

作用于指定类型的所有元素并执行某些操作。

然后,我使用某种工厂模式创建了此AbstractProcessor的具体类实现,同时保留了公共超类型AbstractProcessor的列表,然后调用了process方法通过它们的多态性。这些具体的类之一可能像XYZProcessor<T extends CtElement> extends AbstractProcessor<T>这样。

我现在创建这些具体的处理器,例如new XYZProcessor<CtNamedElement>(),其中CtNamedElementCtElement的子类型,因此process的{​​{1}}方法仅被调用与CTNamedElements。但是XYZProcessor方法似乎被所有类型为process的可见元素调用,而不仅仅是我想要的CtElement类型的那些元素。

有人知道这里发生了什么吗?

编辑:相关代码:

创建这样的处理器

CtNamedElement

类定义:

case CLASS:
 //CtClass is subtype of CtNamedElement
 this.setProcessor(new AnnotatedWithProcessor<CtClass>(targetName, attributeMappings, metapackage));
break;

然后像这样调用处理器:

public class AnnotatedWithProcessor<T extends CtNamedElement> extends AbstractProcessor<T> {
    @Override
    public void process(T element) {
     //do stuff here with elements of correct type
    }

1 个答案:

答案 0 :(得分:0)

好像您在某处这样非法转换,但是如果不看更多实现,很难说清楚。谁在呼叫XYZProcessor::process?为什么期望定义一个通用接口来执行任何类型的过滤?

在这里要在黑暗中拍照,但似乎您可能想要的是类型与处理器的查找映射。这种代码可能会变得凌乱,因此最好使用经过良好测试的方法来限制对此映射的访问:

private final Map<Class, Object> processorMap = new HashMap<Class, Object>();

public <T extends CtElement> void putProcessor(
    Class<T> elementClass, 
    AbstractProcessor<? extends T> processor
) {
     processorMap.put(elementClass, processor);
}

@SuppressWarnings("unchecked")
public <T extends CtElement> AbstractProcessor<? extends T> getProcessor(
    Class<T> elementClass,
) {
    return (AbstractProcessor<? extends T>) processorMap.get(elementClass);
}

现在,当您搜索处理器时,可以使用此映射找到要调用的正确实现:

public void <T extends CtElement> process(T element) {
    getProcessor(element.getClass()).process(element);
}

您可能想要扩展此功能,以允许每个类有多种实现,或者使用processorMapelement.getClass()过滤所有有效处理器的Class::isInstance,然后为每个有效密钥进行处理。 / p>