来自成员函数的可运行实例

Instance of runnable from a member function

class test
{
        public static void main(String[] args)
        {
                System.out.println("Start");
                MyClass myClass = new MyClass();
                myClass.runFunc();
                System.out.println("End");
        }
}

class MyClass
{
        public void hello()
        {
                System.out.println("Hello");
        }
        public void runFunc()
        {
                Runnable run = this::hello;
                new Thread(run).start();
        }
}

这里 hello 是 MyClass 的成员函数,而不是实现 Runnble 的任何 class 的实例。但是赋值 Runnable run = this::hello; 仍然没有失败,并且 hello 函数正在新线程的上下文中执行。

我知道 Runnable 也可以用 lambda 表达式初始化,但这里也不是这种情况。

我是 Java 的新手。有人可以解释一下这是如何工作的以及这种行为背后的逻辑是什么。

这个:

Runnable r = this::hello;

只是语法糖(不要敲它;大多数语言结构都是)用于:

Runnable r = () -> this.hello();

这是语法糖*:

Runnable r = new Runnable() {
    @Override public void run() {
        MyClass.this.hello();
    }
}

现在应该很明显了,为什么,或多或少,所有这些都是有效的。

*) 不完全; lambdas 有一些略有不同的行为,只有当你做 'bad' 事情时才会出现(比如试图在这个可运行的上同步()或试图获得它的声明 class。但只要你不这样做做到这一点,所有三个片段都可以互换。

这一行:

Runnable run = this::hello;

是lambda的简写,实际上是:

Runnable run = new Runnable() {
    @Override
    public void run() {
        MyClass.this.hello();
    }
}

您不是在创建一个 Runnable“属于”您的成员函数,而是使用调用您的成员函数的 run() 方法构建一个新的 Runnable

以下在功能上也是等效的:

Runnable run = () -> this.hello();