快速 Java 匿名 function/class 问题

Quick Java Anonymous function/class question

我知道匿名函数在 JS 中是如何工作的,但在 Java.

下面我有一个匿名 class(我只是使用线程 class 作为我所见的示例),我在其中覆盖了 运行() 函数,然后在 class.

上调用 .start()
new Thread() {
    @Override
    public void run() {
        System.out.println("Hello from the anonymous class thread");
    }
}.start();

所以这行得通,但 IntelliJ 希望我将其重写为:

new Thread(() -> System.out.println("Hello from the anonymous class thread")).start();

我了解大部分语法,但对如何覆盖 运行() 函数有点困惑。根据我的理解,没有参数被传递到 Thread class (所以我假设没有任何参数被传递到构造函数)。现在我感到困惑的地方就在这里。它没有在任何地方声明它 覆盖 运行() 函数。这是 Thread class 的特例还是我遗漏了什么?

希望我解释清楚,在此先感谢!

run() 函数被隐式覆盖,因为它是 Runnable 接口的唯一方法,这使其成为 功能接口 。函数式接口只有一个抽象方法。这种特殊的 属性 接口允许您使用 lambda 表达式 隐式 实现它。编译器知道您正在提供 Runnable.run() 方法的实现,因为它是接口中的唯一方法。

如果您看一下 Runnable 界面,您会发现它装饰有 @FunctionalInterface 注释。此注释确保装饰接口永远不会有多个抽象方法(否则编译器将失败)。请注意,为了使隐式 lambda 功能起作用,不需要此注释。

IntelliJ 向您建议的语法不仅仅是对您的原始代码的“间接”翻译,而且实际上并没有像您的原始代码那样覆盖 Thread.run

您的原始代码创建了 Thread 的匿名子 class 并覆盖了 run,而 IntelliJ 提议的语法调用 Threadthis constructor接受 Runnable。 lambda 表达式表示 Runnable。如果我们将 lambda 表达式“扩展”为匿名 class,我们实际上会这样做:

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello from the anonymous class thread");
    }
}).start();

所以我们正在创建 Runnable 的匿名实现,并改为实现 Runnable.run

It doesn't state anywhere that it is overriding the run() function.

是的,但是 runRunnable 接口中唯一的抽象方法,因此 Java 能够判断出您正在覆盖该方法。