具有接受对象 class 的方法时双重分派

Double Dispatch when having a method that accepts Object class

我有一个映射器 class 的实现,它接受对象作为 map(Object object) 函数之一的参数。其余 map(T t) 函数接受整数或 Class 等

当我尝试传递一个 int 时,它会自动装箱为 Integer 并调用 map(Object object) 而不是 map(Integer integer)

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

上述方法接受每个对象。

当您有一个也接受对象的方法时,是否有任何类型的解决方案可以解决 Java 对象的双重分派问题?

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) 被调用。

关于您的对象,编译器只知道它们是对象,即 Object 的实例。所以 map(Object) 被调用了。

如果您的 map 方法需要根据传递的对象类型做一些不同的事情,那么它应该获取对象的具体类型,并采取相应的行动(使用 instanceofgetClass(), 或其他).

备选方案确实是使用多态性。但要做到这一点,调用者必须提供一个 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));