Java 8 Series: Target Types and Contexts for Lambda Expressions

In the we learned the nuts and bolts of lambda expressions. This time you’ll get answers to the questions which Java types are qualified for holding lambda expressions and at which places within your code they can be used.

‘Plain Old’ Functional Interfaces

We all know and already used them: Interfaces like Runnable or ActionListener. For instance, Runnable gets utilized for handing round execution code that should be run within a thread, while ActionListener defines a handler for user interface actions like button clicks. Those so called functional interfaces are characterized by the possession of a single abstract method declaration1.

Since Java 8 functional interfaces can optionally be annotated with @FunctionalInterface in order to force the compiler to validate the intended ‘functional interface-ability’. While they are restricted in having only one method declaration, functional interfaces can still have any number of default and static methods definitions:

So if you would add an additional method declaration to the above interface then you would get an compile error.

So what?

But why are we talking about functional interfaces? Well, Java types satisfying the functional interface requirements described above are perfect targets for lambda expressions. That’s because they hold information about the

  1. return type,
  2. amount of parameters,
  3. parameter types,
  4. and the exception(s) that may be thrown

in the signature of their single abstract method. Indeed they are the only types that can hold lambda expressions.

And where can I use ’em?

So functional interfaces are target types for lambda expressions. Consequently this means that you can use lambda expressions at contexts where functional interfaces can appear:

  • Variable Assignments
  • Array Initializers
  • Return Statements
  • Constructor Parameters
  • Method Parameters
  • Cast Expressions
  • Conditional Expressions
  • Lambda Expression Bodies

The last example contained the Supplier<T> functional interface type. What it does is to simply supply an object of type T by means of its get() method. It’s one of the new functional interface types from the package java.util.function that will be introduced with Java 8.

Conclusion

You might have asked yourself why there is not a dedicated Java type for lambda expressions. Indeed there were early considerations to introduce so called structural function types which would look like (int)->String, i.e. a function which takes an integer and returns a string. However, among others one wanted to avoid a mixture of structural2 and nominal3 types in the Java type system (nominal types prevail in Java). Furthermore functional interfaces get extensively applied in Java -based libraries which means that there already exist suitable targets for lambda expressions.

In the next part of this series we will deal with constructor and method references.

Other Posts in this Series

References

Footnotes

  1. Indeed they were formally called SAM-types, where SAM is an acronym for single abstract method
  2. Structural Type System
  3. Nominal Type System