shulito
shulito

Reputation: 826

Lambda overloaded method

I'm new to lambdas and funtional interfaces. I'm trying to implement a RowListener functional interface (ActiveJDBC ORM) with a lambda but I get a compiler error and I don't really now why.

Here's how the anonymous class old-style looks like:

db.find("some query", new RowListener() {
        @Override
        public boolean next(Map<String, Object> arg0) {
            // TODO Auto-generated method stub
            return false;
        }
    });

Here's what I want to do:

db.find("some query", map -> {
        // whatever
    });

The error that gives me is:

The method find(String, Object...) in the type Base is not applicable for the arguments (String, ( map) -> {})

I think it's trying to apply the lambda to an overloaded method of 'find' wich doesn't take a RowListener as an argument, but I'm not really sure why.

Any light you can shed on this would be helpful.

Upvotes: 1

Views: 471

Answers (2)

shulito
shulito

Reputation: 826

Ahh, the error message confused me. I added a boolean return value and it compiles :)

Upvotes: 0

Holger
Holger

Reputation: 298103

A lambda expression of the form

map -> {
        // whatever
    }

is not compatible with the functional signature. According to your inner class example code, it has to return a boolean value. Hence, it has to be either

map -> {
        // whatever
        return false;
    }

or

map -> /* simple expression, e.g.: */ false

In case of overloaded methods, the compiler uses the shape of a lambda expression, i.e. whether it’s value compatible or void compatible (see JLS §15.27.2), to determine which methods are applicable.

Keep in mind that if the lambda’s body is a block containing conditional code, all code flows which can complete normally must return a value.

Since all methods are inapplicable, the compiler picks one to report an error, according to an algorithm which is independent of the fact that one argument is a lambda expression. It seems that it reports against the method find(String, Object...) because that method can consume most kind of arguments. You could say, that method could consume anything, if there weren’t lambda expressions.

That might be a compiler specific behavior which has been implemented before lambda expressions were to consider. However, that’s only the error reporting behavior, the primary problem is the lambda expression which is not value compatible. Fixing it should solve all problems.

Upvotes: 2

Related Questions