Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is it possible to use Lambda Expressions in Thread class?

Tags:

lambda

java-8

Im learning Lambda Expressions and I know it is possible to use them for example in the Runnable functional interface and in Thread class.

I tried to create my own:

package tests;

public interface Blabla
{
    public void doStuff();
}

And this simple test compiled:

Blabla bla = () -> System.out.println("Lol");

Then I tried to make a class like Thread

package tests;

public class Dodo implements Blabla
{
    public void doStuff()
    {
        // TODO Auto-generated method stub

    }
}

And this doesnt compile:

 Dodo dodo = () -> System.out.println("LoL");

And I cant find anywhere explaining how to create a class which allows the use of lambda expressions.

How can Thread allow the use of Lambda Expressions while not being an Interface?

like image 896
Xkynar Avatar asked Jul 20 '14 03:07

Xkynar


1 Answers

How can Thread allow the use of Lambda Expressions while not being an Interface?

I think you're a little confused by how the Thread class uses lambdas. The lambdas are not converted into an instance of the Thread class itself; instead, the lambdas are converted into an instance of a subclass the Runnable functional interface, which is then passed to a Thread constructor that has been overloaded to take a Runnable object.

Thus, when you do something like this:

new Thread(() -> System.out.println("Lol")).start();

The lambda wasn't converted into the Thread object you're creating. Instead, it was converted into the Runnable object that is passed to the Thread constructor.

This is clearer if you separate the lambda from the Thread object:

Runnable temp = () -> System.out.println("Lol");

new Thread(temp).start();

It might help to think of a Thread executing a function rather than being a function. You have to keep the function that the Thread is executing distinct from the Thread itself.

Note that the way lambdas are converted into objects is an implementation detail and is subject to change in future Java releases (Java 1.8.0_11 is the most recent release at the time this answer was written). See Stuart Marks' comment below.


And I cant find anywhere explaining how to create a class which allows the use of lambda expressions.

If I'm understanding you correctly, you wish to write a class such that you can create a lambda based on that class.

Unfortunately, you can't. Take a look at the Java Language Specification, section 15.27:

Evaluation of a lambda expression produces an instance of a functional interface (§9.8).

The key point here is that the lambda is an instance of an interface. Thus, you can't use a lambda to directly subclass a class. The rationale for this can be found in this email by Brian Goetz in the JDK lambda-dev mailing list (Thanks to Stuart Marks for pointing this out!); in short, the decision was made at least partially so Java could continue to evolve in new directions.

What you can do is write a class whose constructor(s) and/or method(s) take one or more functional interfaces as arguments, letting you use the class with lambdas by passing instances of the functional interface around (like the Thread class). At the moment (and as far as I know), that's pretty much as good as it gets.

like image 79
awksp Avatar answered Sep 19 '22 02:09

awksp