Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda Expression without types

I understand the syntax of the Java8 lambda expressions but why does the following code work without a specific type declaration of x? Why is "baz" being printed?

public class LambdaExpressions {

    interface Foo {
        void bar(Object o);
    }

    static void doo(Foo f) {
        f.bar("baz");
    }

    public static void main(String[] args) {

        doo( x -> {System.out.println(x);});
    }

}
like image 825
Nemo_Sol Avatar asked Oct 18 '16 20:10

Nemo_Sol


People also ask

Is it mandatory to declare type of parameter in lambda expression?

Optional type declaration − No need to declare the type of a parameter. The compiler can inference the same from the value of the parameter. Optional parenthesis around parameter − No need to declare a single parameter in parenthesis. For multiple parameters, parentheses are required.

Can we use lambda expression without interface?

You do not have to create a functional interface in order to create lambda function.

Can a lambda expression have no parameters?

Lambda syntax only requires parentheses around more than one parameter, or when there is no parameter at all.

Can lambda expression have data type?

The lambda expressions have a very simple, precise syntax and provide flexibility to specify the datatypes for the function parameters. Its return type is a parameter -> expression body to understand the syntax, we can divide it into three parts.


2 Answers

Since the interface is a standard functional interface

It's a functional interface because it contains only one abstract method. This method takes one parameter and returns a [void] value

(Reworded for this question)

The lambda expression x -> { System.out.println(x); } can be re-written as an anonymous class.

new Foo() {
    @Override
    public void bar(Object x) {
        System.out.println(x);
    }
}

When you call doo, you pass this functional interface as f, which then executes f.bar("baz");, so "baz" is x, and it is printed.

All in one main method, this would look like

public static void main(String[] args) {
    Foo f = new Foo() {
        @Override
        public void bar(Object x) {
            System.out.println(x);
        }
    };

    f.bar("baz");
}
like image 146
OneCricketeer Avatar answered Oct 02 '22 17:10

OneCricketeer


The type of the parameter x is inferred as per the specification:

The formal parameters of a lambda expression may have either declared types or inferred types. These styles cannot be mixed: it is not possible for a lambda expression to declare the types of some of its parameters but leave others to be inferred. Only parameters with declared types can have modifiers.

In this case, the compiler infers the type to be Object since the method accepts a functional interface with a method accepting an Object. Also mentioned in that section of the spec:

If the formal parameters have inferred types, then these types are derived (§15.27.3) from the functional interface type targeted by the lambda expression.

like image 31
M A Avatar answered Oct 02 '22 17:10

M A