首先,这并不特定于BiFunction。所以你基本上是在问,你可以嵌套多深的方法调用,简单的答案是 Java 编程语言本身并没有指定限制。
存在可能限制数量的技术限制,但这些是技术限制,而不是规范限制。当技术发展而不改变规范时,它们可能会被取消。
作为Alain O'Dea has explained,如果最后一条指令应该被异常处理程序覆盖,则方法的代码大小限制为 65535 字节或 65534 字节。此代码大小支持的嵌套方法调用数量取决于某些因素。例如,您使用的是interface,并且接口方法调用使用的字节数比具体的类方法调用(invokevirtual 指令)多,此外,您使用的是BiFunction<Integer, Integer, Integer>,而不是直接的IntBinaryOperator,因此每次调用都涉及对int 需要额外代码的值。
但是无论如何还有另一个技术限制,编译器实现。当尝试使用更高的嵌套计数编译您的示例时,javac 从命令行运行,在 1500 个嵌套调用处以 stackoverflow 终止,而 Netbeans(使用与 javac 相同的编译器代码)在IDE 开始出现奇怪的行为(我猜,它不能很好地处理编译器/语法荧光笔的堆栈溢出)。
这表明 IDE 具有更高的堆栈大小或环境设置中的其他差异影响了表达式解析之前的初始堆栈深度。由此得出结论,在实践中没有硬性限制。您可能能够编写代码,一个编译器可以毫无问题地编译,而另一个编译器则退出 - 最大限度地解决这个问题不是一个好主意。
毕竟,你问题的代码可以写成:
public static int methodContainingMethod(
int a, int b, int c, BiFunction<Integer, Integer, Integer> theFunction) {
int value = theFunction.apply(a, b);
for(int i=0; i<asDeepAsYouWannaGo; i++)
value=theFunction.apply(value, c);
return value;
}
虽然我认为,你的想法更像是:
public static int methodContainingMethod(
IntBinaryOperator theFunction, int first, int second, int... rest) {
int value = theFunction.applyAsInt(first, second);
for(int next: rest) value=theFunction.applyAsInt(value, next);
return value;
}
或
public static OptionalInt methodContainingMethod(
IntBinaryOperator theFunction, int... arguments) {
return IntStream.of(arguments).reduce(theFunction);
}