说我有这个界面:
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
,反之亦然,也许可以吗?似乎您应该能够转换一个采用另一个方法的参数超集的方法。
答案 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);
}
}