简体   繁体   中英

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();
        }
}

Here hello is a member function of MyClass not an instance of any class which implements Runnble . But still the assignment Runnable run = this::hello; doesn't fail and the hello functions is getting executed in the context of the a new thread.

I know a Runnable can can be also initialized with a lambda expression but it's not the case here either.

I am new to Java. Can somebody please explain how this is working and what is the logic behind this behavior.

This:

Runnable r = this::hello;

is merely syntax sugar (don't knock it; most language constructs are) for:

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

which is syntax sugar* for:

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

It should now be obvious why, and more or less how, all of this works.

*) Not entirely; lambdas have some slightly different behaviours which show up only if you do 'bad' things (such as trying to synchronize() on this runnable or attempt to obtain its declaring class. But as long as you don't do that, all three snippets are interchangible.

This line:

Runnable run = this::hello;

is lambda short-hand, which is really:

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

You're not creating a Runnable "of" your member function, but rather constructing a new Runnable , with a run() method that calls your member function.

The following would also be functionally equivalent:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM