嵌套BiFunction的深度(或限制,如果有的话)是多少

时间:2015-06-28 22:59:34

标签: java functional-programming java-8

我一直在玩BiFunctionjava.util.function)。我举了一些例子,我有一个问题。

  

是否可以嵌套操作的次数有限制   与BiFunction?是否像嵌套假设add(a, b)一样简单   方法多次想要?

e.g。三个嵌套theFunction.apply()

public static int methodContainingMethod
         (int a, int b, int c, BiFunction<Integer, Integer, Integer> theFunction) {
    return theFunction.apply(theFunction.apply(theFunction.apply(a,b),c),c),c);
}

四个嵌套theFunction.apply()

return
  theFunction.apply(theFunction.apply(theFunction.apply(theFunction.apply(a,b),c),c),c),c);
  

on and on ...嵌套的数量可以继续,我测试了   将函数嵌套十次以上。

我对于需要多少嵌套没有确切的要求......但我很好奇有多少嵌套可以做到?

2 个答案:

答案 0 :(得分:6)

首先,这并不是BiFunction以任何方式具体的。所以你基本上都在问,嵌套方法调用有多深,简单的答案是Java编程语言本身没有指定限制。

存在可能限制数量的技术限制,但这些是技术限制,而不是说明书的限制。当技术发展而不改变规范时,它们可能会被解除。

作为Alain O'Dea has explained,如果最后一条指令应该由异常处理程序覆盖,则方法的代码大小限制为65535字节或65534字节。此代码大小支持的嵌套方法调用量取决于某些因素。例如,您正在使用interface和接口方法调用使用比具体类方法调用(调用虚拟指令)更多的字节,此外,您使用BiFunction<Integer, Integer, Integer>而不是直接IntBinaryOperator所以每次调用都涉及int值的装箱,需要额外的代码。

但是还有另一个技术限制,即编译器实现。当尝试使用更高的嵌套计数编译示例时,javac从命令行运行,以1500嵌套调用的stackoverflow结束,而Netbeans(使用与javac相同的编译器代码)设法编译2000 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);
}

答案 1 :(得分:4)

我不知道对此有固有的表达式限制,但实际上它将受到JVM方法大小限制65534字节的限制:

  

end_pc是独占的这一事实是Java虚拟机设计中的历史错误:如果方法的Java虚拟机代码正好是65535字节长并且以1字节长的指令结束,那么该指令不能被异常处理程序保护。编译器编写器可以通过将任何方法,实例初始化方法或静态初始化程序(任何代码数组的大小)生成的Java虚拟机代码的最大大小限制为65534字节来解决此错误。

来源:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.3