具有接受Object类的方法时的Double Dispatch

时间:2016-07-02 09:00:14

标签: java visitor-pattern double-dispatch

我有一个Mapper类的实现,它接受一个map(Object object)函数中的Object作为参数。其余的map(T t)函数接受整数或类等。

当我尝试传递一个int时,它将Autoboxed变为Integer并调用map(Object object)而不是map(Integer integer)

我为Double Dispatch做了一些研究,发现我可以使用访客模式。但这不适用于我的情况,因为我没有传递自定义对象,我可以让它们实现与accept()的接口。

上述方法接受每个对象。

当你有一个接受Object的方法时,是否有任何解决方案可以使用Java对象进行Double Dispatching?

public BaseMatcher map(Object object) {
        return something();
    }

    public BaseMatcher map(Integer integer) {
        return somethingOther();
    }

    public BaseMatcher map(Class<? extends Exception> klass) {
        return somethingOtherOther();
    }

对这些map()函数的调用如下:foo(Object object) { mapper.map(object); }导致map(Object object)被调用。

1 个答案:

答案 0 :(得分:2)

所有编译器都知道你的对象是它们是对象,即Object的实例。所以map(Object)正在被调用。

如果你的map方法需要根据传递的对象的类型做一些不同的事情,那么它应该得到对象的具体类型,并相应地采取行动(使用instanceofgetClass(),或者whataver)。

替代方案确实是使用多态性。但要做到这一点,调用者必须提供一个Mappable集合,而不仅仅是一组对象:

private interface Mappable {
    BaseMatcher mapMe(Mapper mapper);
}

public class IntegerMappable {
    private final Integer value;

    public IntegerMappable(Integer value) {
        this.value = value;
    }

    @Override
    public BaseMatcher mapMe(Mapper mapper) {
        return mapper.map(this.value);
    }
}

当你想要映射对象时,你将它们包装到适当的Mappable(或使用lambda)中:

List<Mappable> mappables = new ArrayList<>();
mappables.add(new IntegerMappable(2));
mappables.add(new StringMappable("hello");
mappables.add(mapper -> mapper.map(42));