3

Cannot convert functional interface with generic method into lambda expression.
Following code is working. It is without lambda expression i.e. using anonymous class.

public interface Pro{
    public <T> void callee(T t);
}

public void fun(Pro obj){}


public void implement() {
    fun(new Pro() {
        @Override
        public <Integer> void callee(Integer t){}
    });
}

I cannot understand how to use lambda expression instead of anonymous class.
After trying it myself I used the hint shown in netbeans. I used the shown bulb to do it.

enter image description here

And here is what I got, an ERROR.

public void implement() {
    fun((Integer t) -> {
    });
}

It is showing error. What is the correct lambda expression to be used here?
Here is the error :

one\LambdaScopeTest.java:18: error: incompatible types: invalid functional descriptor for lambda expression
    fun((Integer t) -> {
        ^
method <T>(T)void in interface Pro is generic
where T is a type-variable:
     T extends Object declared in method <T>callee(T)
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get
full output
2
  • 2
    "It is showing error" is never enough information. What error, and where? Commented Aug 11, 2014 at 14:18
  • 1
    Funny how, IntellIJ IDEA does not suggest "Use lambda expression" but only the fact that with <Integer> you hide Integer class. Suggested the replacement only after i generalize the interface and not the method. Netbeans was wrong with recognize possible replacement with lambda Commented Aug 11, 2014 at 14:28

1 Answer 1

8

The main problem is that you've got a generic method instead of a generic interface. That doesn't make a lot of sense. As soon as you make the interface generic instead, it works:

@FunctionalInterface
interface Pro<T> {
    void callee(T t);
}

public class Test {    
    public static <T> void fun(Pro<T> obj){}

    public static void main(String[] args) {
        fun((Integer t) -> {});
    }
}

It makes much more sense for the interface to be generic, as then it makes sense to have different implementations for different types. For the method to be generic suggests that every implementation should be able to accept any value of any type, because the caller would be specifying it - which doesn't make sense if you then use a lambda expression with a specific type.

Your original version is only working because you're declaring a generic type parameter called Integer... you're not specifying an implementation for the Integer type. In other words, this:

fun(new Pro() {
    @Override
    public <Integer> void callee(Integer t){}
});

is equivalent to:

fun(new Pro() {
    @Override
    public <T> void callee(T t){}
});

... and I don't know of a way of representing that as a lambda expression. Basically, I think your original interface is inappropriate for lambda expressions.

Sign up to request clarification or add additional context in comments.

6 Comments

I am sorry, but It is not my answer.
@afzalex: What do you mean? Without any more detail, I can't help you any further.
@afzalex: As far as I'm aware, you can't use a lambda expression with your interface in its current form. Your interface needs to change, and your existing code probably doesn't mean what you think it means.
You have completely changed my question. I know it can work this way. But why it is not working when I am making function to be generic, not class
@afzalex: I've shown you how to fix things, and explained why your original interface didn't make sense. Did you understand that the Integer in your original code didn't mean java.lang.Integer? I'm pretty sure the answer to your original question is "You can't." I was trying to be more helpful than that...
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.