Lambda Expressions in Java 8 (Part 4)

Kasun Dissanayake
4 min readMay 2, 2019

In this tutorial, we are going to learn the Backward Compatibility of Lambda Expressions and more details about Functional Interfaces.

Now you know Lambda Expressions don’t have new function type in Java. We have reused the interfaces as the type of lambda expressions. There is a reason to reuse interfaces as a type of lambda expressions. The most important reason is backward compatibility.

If we use a new Lambda type instead of interfaces we have to rewrite all the code when we got a new lambda type. So the advantage of interface is we can use interfaces which are already existing instead of rewriting code.

Let’s get an example of Thread and a Runnable. You should know these things.

  • Runnable Interface has a method called a run()
  • To create a new Thread you have to create a new instance of Runnable
  • Use that instance to create a new Thread

You can use Lambda Expressions to create a new Runnable. Remember you need an Interface with one method to create Lambda Expression. For that Runnable interface is most suitable interface because it has only one method called run.

Here I am going to demonstrate how you can use lambda to take the place of an instance of Runnable.

First, create a new Thread and pass an instance of Runnable to it (Here I am using an Anonymous Inner Class).

package lambdatutorial;/**
*
* @author Kasun Dissanayake
*/
public class RunnableLambda {

public static void main(String args[]){

Thread myThread = new Thread(new Runnable(){
@Override
public void run() {
System.out.println("Inside Runnable Method");
}

});
myThread.run();
}

}

Copy above code segment and run it. You will get a result like this.

Now we can create a lambda expression which has the same signature and with the same run method in the Runnable interface.

NOTE: Remember, this works because Runnable has a single method. If it had more than one method, you could not have written a lambda function of that type.

Now write the same code segment using lambda expressions. Now you know how to do it.

package lambdatutorial;/**
*
* @author Kasun Dissanayake
*/
public class RunnableLambda {

public static void main(String args[]){

Thread myThread = new Thread(new Runnable(){
@Override
public void run() {
System.out.println("Inside Runnable Method");
}

});
myThread.run();

Thread myLambdaThread = new Thread(() -> System.out.println("Inside Lambda Runnable Method"));

myLambdaThread.run();
}

}

Create an instance of Thread and run the run() method. Now you will get a result like this. I have just created a simple inline Lambda rather than all the boilerplate code.

The Thread class does not know any pattern. So Lambda pretty much behaves like an instance as the previous example. This is the magic of having the interface mechanism for declaring Lambdas. You can get huge backward compatibility. Now all the APIs that come with Java 8 can accessible with Lambdas. The only constraint is the interfaces that all the APIs expected should have one abstract method. These interfaces are called Functional Interfaces.

Functional Interfaces

You know interfaces are used as a type for the lambda expressions. And it should consist of one abstract method. You know in Java 8 you can write interfaces which have an implementation. Before Java 8 you cannot implement the abstract method body. Now you know you can have as many methods in the interface but you can have one abstract method only. This type of interface we called Functional Interface.

Functional Interface something that a property of an interface. But if we define the functional interface as the normal interface with one abstract method someone will add another abstract method to that interface and that will give an error. It will no longer a functional interface. So Java 8 has a specific way of marking functional interfaces. Let me get an example to explain this. Take the previous example in Tutorial 1.

Let’s say I add one abstract method called another() to Print Interface.

Now you will get a problem. Lambda is going to fail. But you can see the interface is perfect. So How do we know where is the error?

In order to make sure that other developers don’t add another method by mistake to the interface, you can use annotation called @FunctionalInterface. This annotation gives a clue to any other developer that this is meant to be a Functional Interface.

Now I am going to add another abstract method to my Print Interface.

Now you can see an Error saying Invalid Annotation.

The @FunctionalInterface annotation is completely optional. The Java compiler does not require it for your Lambda types. But it is good practice to add it.

Thank You!

--

--

Kasun Dissanayake

Senior Software Engineer at IFS R & D International || Former Software Engineer at Pearson Lanka || Former Associate Software Engineer at hSenid Mobile