Java lambda表达式如何引用自身?

Java lambda表达式如何引用自身?,lambda,java-8,Lambda,Java 8,我发现,将旧式函数与新的Java-8 lambda函数和并行处理进行比较,可以提供非常丰富的信息。有一件事我不太明白,那就是lambda函数有一个限制:第4页: 3.3先决条件 尽管lambda表达式的目的是作为一个更为复杂的概念- 替代 艾克 ,它们不是完全的替代品。 有几个先决条件 lambdifactor 检查 在重构 艾克 变成一个lambda表达式。这些 前提条件是lambda表达式的固有特性 用Java实现,不受我们工具的限制。 (P1) 艾克 必须从接口实例化。实例 抽象或具体类无

我发现,将旧式函数与新的Java-8 lambda函数和并行处理进行比较,可以提供非常丰富的信息。有一件事我不太明白,那就是lambda函数有一个限制:第4页:

3.3先决条件 尽管lambda表达式的目的是作为一个更为复杂的概念- 替代 艾克 ,它们不是完全的替代品。 有几个先决条件 lambdifactor 检查 在重构 艾克 变成一个lambda表达式。这些 前提条件是lambda表达式的固有特性 用Java实现,不受我们工具的限制。 (P1) 艾克 必须从接口实例化。实例 抽象或具体类无法转换为lambda 表达。 (P2) 艾克 必须没有字段,并且只声明一个方法。 lambda表达式表示单个匿名函数- 反倾销;因此 艾克 用多种方法都不能 转换为单个lambda表达式。 (P3) 艾克 不得引用 这 或 超级的 . 在里面 一个lambda表达式, 这 和 超级的 在词汇范围内, 也就是说,它们的解释方式与 封闭的环境,例如,好像它们出现在状态中- lambda表达式前面的表达式[6]。然而,在一个 艾克 它们指的是内部类本身。 (P4) 艾克 不能声明递归方法。为了 执行递归调用时,必须获取对 匿名函数。虽然 lambdifactor 能表演 这种重构可能会引入不必要的复杂性 进入代码和危害的可理解性

在第4页,“AIC不能声明递归方法…lambdificator可以执行此重构…”,如何重构lambda表达式以引用自身?因为根据定义,这些lambda匿名函数没有可引用的名称,也没有对自身的引用(上面第3页)

运行时,
Runnable
r
字段获取对自身的引用


如果您不喜欢添加字段,也可以使用长度为1的数组来存储引用。

源自@Alex的答案:

@FunctionalInterface
public interface SelfRunnable extends Runnable {
  public void run(SelfRunnable this_);

  @Override
  public default void run() {
    run(this);
  }

  public static Runnable runnable(SelfRunnable runnable) {
    return runnable;
  }
}

public interface Test {
  public static void main(String... arguments) {
    final Runnable r = SelfRunnable.runnable(this_ -> this_.run());
    r.run();
  }
}
如上所述,Java实现递归函数的规范方法是一种方法:

然后,如果您需要实现功能性
接口的实例
,可以使用方法引用:

Function<Integer, Integer> fib = MyClass::fib;

这与lambda表达式最接近,因为lambda表达式不仅是运行时生成的类替换匿名内部类的语法糖,而且也是托管要实现的单个抽象方法代码的匿名方法的语法糖


使用普通的递归方法将匿名方法转换为命名方法,同时保持lambda表达式的所有其他属性。这不同于试图为lambda表达式自身提供引用的所有其他解决方案,比如将实例存储到字段中。这些解决方法在语义上并不等价(而且效率较低)。

omg,是时候切换到C了#
public static int fib(int n) {
    return n==0? 0: n==1? 1: fib(n-1)+fib(n-2);
}
Function<Integer, Integer> fib = MyClass::fib;
IntUnaryOperator fib0=MyClass::fib;