简体   繁体   中英

Lambda expression gives “invalid tokens” syntax error in Java

I just started to learn about Lambda Expression and I did something like this:

public class LambdaTest {

    public static void main(String[] args) {
        int num = returnNumber((num) -> { return 4 });
    }

    public static int returnNumber(int num) {
        return num;
    }
}

But it gives me an error: "invalid tokens". Here is an image:

Can someone please explain me what's wrong? It's just a test.

I have Java 1.8 supported in my Eclipse installation (Luna 4.4).

There are a few restrictions on what can be done in the body of the lambda, most of which are pretty intuitive—a lambda body can't “break” or “continue” out of the lambda, and if the lambda returns a value, every code path must return a value or throw an exception, and so on. These are much the same rules as for a standard Java method, so they shouldn't be too surprising.

Reference : http://www.oracle.com/technetwork/articles/java/architect-lambdas-part1-2080972.html

The method's body has the effect of evaluating the lambda body, if it is an expression, or of executing the lambda body, if it is a block; if a result is expected, it is returned from the method.

If the function type's result is void, the lambda body is either a statement expression or a void-compatible block.

Reference : http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.27.4

The syntax error is pretty straight-forward. It says that there is a ; missing after a statement and that's in no ways other than with statements outside lambda expressions. If you write (num) -> { return 4 } , there must be a semicolon after return 4 as it would have to be at every place where you can write return 4 (I'm astounded why nobody else was capable of telling you that).

You can write a lambda expression returning an int in two ways, either like (num) -> { return 4; } (num) -> { return 4; } or, much simpler, as num -> 4 (here, without semicolon).

But, of course, you can't call returnNumber(int num) with a lambda expression as parameter as it expects an int and not a functional interface . Your compiler will tell you that once you fixed the structural syntax error of the missing semicolon.

Lambdas are just implementations for method of functional interface (interfaces with one abstract methods), but in case of

returnNumber(int num)

lambdas can't be used because:

  • int is not an functional interface
  • so lambdas can't be used to supply implementation of its only abstract method (since primitive types are primitive - they have no methods).

Before lambdas to execute method like

method(SomeInterface si){...}

you would need to either create separate class which would implement this interface

class MyClass implements SomeInterface{
    void method(Type1 arg1, Type2 arg2){
        //body
    }
}

...
MyClass mc = new MyClass();
method(md);

or add its implementation on fly by creating anonymous class

method(new SomeInterface{
    void method(Type1 arg1, Type2 arg2){
        //body
    }
});

Lambdas can shorten this process by skipping this idiom and letting you focus only on arguments types, and implementation.

So instead of

new SomeInterface{
    void method(Type1 arg1, Type2 arg2){
        //body
    }
}

you can simply write

(Type1 arg1, Type2 arg2) -> { body } // you can actually shorten it even farther 
                                     // but that is not important now

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