使用<void>类型使参数可选?

时间:2019-03-02 04:52:36

标签: java

说我有这个界面:

  public interface IAsyncCallback<T, E> {
    void done(E e, T v);
  }

在某些情况下,我希望某人能够使用:

IAsyncCallback<Void,Object> cb = e -> {};

这样,很明显他们不应该期望第二个参数(第二个参数v始终为null。

这有可能吗?在调和2个参数方法和1个参数方法时有些麻烦,因此它们可以互换。

基本上想找到一种使用泛型使用可选参数的方法,但我很好奇是否有另一种方法可以使用此方法,因为上述技术无效,它需要2个参数,所以您可以不要理会参数,等等。

顺便说一句,如果我有这样的界面:

  public interface IEachCallback<T, E> {
    void done(E e);
  }

我希望您可以将IAsyncCallback强制转换为IEachCallback,反之亦然,也许可以吗?似乎您应该能够转换一个采用另一个方法的参数超集的方法。

1 个答案:

答案 0 :(得分:3)

确实没有一种简单的方法可以使这个变得简单。

一种解决方法是使用IEachCallback界面中的默认方法来实现IEachCallback,并允许用户传递单参数lambda:

public interface IEachCallback<T, E> extends IAsyncCallback<T, E> {

    @Override
    default void done(E e, T t) {
        this.done(t);
    }

    void done(T e);
}

这允许调用者传递一个单参数lambda,但仍然带来分配问题:

//there's no way to assign or pass as argument directly
//Otherwise users have to do this type cast:
IAsyncCallback<Void,Object> cb = (IEachCallback<Void, Object>) e -> {};

要解决此问题,我将向IEachCallback添加静态工厂方法:

public interface IEachCallback<E> extends IAsyncCallback<Void, E> {

    @Override
    default void done(E e, Void t) {
        this.done(e);
    }

    void done(E e);

    static <E> IAsyncCallback<Void, E> ofVoid(IEachCallback<E> callback) {
        return (e, v) -> callback.done(e);
    }
}

这使用户可以以更简单的方式调用它:

IAsyncCallback<Void,Object> cb = IEachCallback.ofVoid( e -> {});

为了进一步改进,您可能需要将其移至父界面,并完全取消子界面:

public interface IAsyncCallback<T, E> {
    void done(E e, T v);

    static <E> IAsyncCallback<Void, E> ofConsumer(Consumer<E> callback) {
        return (t, e) -> callback.accept(t);
    }
}