快速 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 提议的语法调用 Thread
的 this 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.
是的,但是 run
是 Runnable
接口中唯一的抽象方法,因此 Java 能够判断出您正在覆盖该方法。
我知道匿名函数在 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 提议的语法调用 Thread
的 this 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.
是的,但是 run
是 Runnable
接口中唯一的抽象方法,因此 Java 能够判断出您正在覆盖该方法。