Mario Ishac
Mario Ishac

Reputation: 5907

How to allow a consumer of more precise type to be passed in as a consumer of a less precise type?

I have this following two functional interfaces:

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);
}

I also have the following method:

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

Is there any way I can allow an IndexIntPairConsumer to be passed in the above method (since a consumer of ints can accept bytes)? I'm required to use primitives in the method signatures rather than the associated classes such as Integer and Byte, so any abstraction becomes much more difficult.

Upvotes: 1

Views: 73

Answers (2)

Holger
Holger

Reputation: 298439

Without changing the type hierarchy (e.g. the way suggested in this answer), an adaptation step is unavoidable, as IndexBytePairConsumer and IndexIntPairConsumer are two different types. The smallest adaptation step would be

// given
IndexIntPairConsumer consumer = …

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

As you said in your question, a consumer of ints can accept bytes, so the accept method of an IndexIntPairConsumer is a valid target for a method reference where an IndexBytePairConsumer is expected.

Upvotes: 2

talex
talex

Reputation: 20544

Here is what I invented for you.

Define

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);
}

and you can use it

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

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

Upvotes: 3

Related Questions