说我有以下界面:

@FunctionalInterface
public interface First {
   int fun(int a);
}

并且
@FunctionalInterface
public interface Second extends First {
   default int fun(int a) { fun(a, a); }

   int fun(int a, int b);
}

然后,如果我在某处使用First的方法可以执行,例如:
methodThatTakeFirst(val -> val + 1);

但我也希望能够传递Second,例如:
methodThatTakeFirst((v1, v2) -> v2 * v2);

但是,这仅在我像这样投射lambda时有效:
methodThatTakeFirst((Second) (v1, v2) -> v2 * v2);

我的问题是:有没有一种方法可以设计这种模式而不必将lambda强制转换为子接口?还是处理这种情况的最优雅的方式是什么?

最佳答案

您可以重载methodThatTakeFirst,以便它也接受Second的一个实例作为参数,并委托给methodThatTakeFirst(First first):

void methodThatTakeFirst(First first) {
    // play with first
}

void methodThatTakeFirst(Second second) {
    methodThatTakeFirst((First) second); // casting necessary
}

强制转换至关重要,因此编译器实际上将委托给methodThatTakeFirst(First first),否则最终将得到StackOverflowError

我不知道这是否是一个好的设计,但我认为这超出了这个问题的范围。

10-04 11:44