如何允许更精确类型的消费者作为较不精确类型的消费者传入?

时间:2018-12-12 05:29:47

标签: java primitive primitive-types functional-interface pecs

我有以下两个功能接口:

IndexBytePairConsumer.java

package me.theeninja.nativearrays.core;

@FunctionalInterface
public interface IndexBytePairConsumer {
    void accept(long index, byte value);
}

IndexIntPairConsumer.java

package me.theeninja.nativearrays.core;

@FunctionalInterface
public interface IndexIntPairConsumer {
    void accept(long index, int value);
}

我还有以下方法:

public void forEachIndexValuePair(IndexBytePairConsumer indexValuePairConsumer) {
    ...
}

是否可以通过上述方法传递IndexIntPairConsumer(因为int的使用者可以接受字节)?我需要在方法签名,而不是诸如IntegerByte之类的关联类,因此任何抽象都变得更加困难。

2 个答案:

答案 0 :(得分:3)

这是我为您发明的。

定义

public interface IndexBytePairConsumer {
    void accept(long index, byte value);
}

public interface IndexIntPairConsumer extends IndexBytePairConsumer {
    default void accept(long index, byte value) {
        this.accept(index, (int) value);
    }

    void accept(long index, int value);
}

您可以使用它

IndexIntPairConsumer c = (a,b)->{
    System.out.println(a + b);
};
forEachIndexValuePair(c);

forEachIndexValuePair((a, b) -> {
    System.out.println(a + b);
});

答案 1 :(得分:2)

在不更改类型层次结构的情况下(例如this answer中建议的方式),由于IndexBytePairConsumerIndexIntPairConsumer是两种不同的类型,因此不可避免地要进行自适应。最小的适应步骤是

// given
IndexIntPairConsumer consumer = …

// call as
forEachIndexValuePair(consumer::accept);

正如您在问题中说的那样,int的使用者可以接受字节,因此accept的{​​{1}}方法是期望使用IndexIntPairConsumer的方法引用的有效目标