3

I'm quite new to lambda expression of Java 8

I tried the following and get compile error

class Test{
    static interface MySupplier {

        Object supply();
    }

    public static void main(String[] args) {
        Object v = value();
        if (v instanceof MySupplier) {
            v = ((MySupplier) v).supply();
        }
        System.out.println(v);
    }

    static Object value() {
//        return () -> "this line will NOT get compiled."; //Error: incompatible types: Object is not a functional interface ???
//        return (Object)(() -> "this line will NOT get compiled, too."); //Error: incompatible types: Object is not a functional interface ???
        return new MySupplier() {

            public Object supply() {
                return "using inner class will work but lambda expression it not";
            }
        };

    }
}

my question is "could it be possible to use lambda expression as normal object. I want to do some thing like

    static Object value(Object v) {
        if (v instanceof MySupplier) {
            return ((MySupplier) v).supply();
        }
        return v;
    }

    public static void main(String[] args) {
//        if some case
        Object v1 = value("value 1");
        // else if some other case
        Object v1 = value(() -> { 
            //do some stuff
            return "value 2";
        });
    }

I did a lot of search but no luck. Is there any workaround? thanks in advance!


update: after having better understanding about lambda expression, the problem is how to let the compiler know the target-type of lambda expression to compile to. so the answer from ernest_k could be improve as

return (MySupplier) () -> "this line will work";
harunaga
  • 141
  • 1
  • 1
  • 10
  • why not return `MySupplier` instead of return `Object` in `value()` method? – Viet Jan 06 '20 at 09:40
  • It's just a test code. Some time I want to return a value like string or integer or object, some time I want to return a function as Lambda for shorter code. So I make it object for return type. But sadly the lambda does not get compiled. – harunaga Jan 06 '20 at 09:44
  • change `static Object value()` to `static MySupplier value()` will work – Viet Jan 06 '20 at 09:46
  • What I wanna do is using functional interface as other object. as I commented in my code, using inner class will get compile but lambda expression will not get compiled. – harunaga Jan 06 '20 at 09:50
  • @harunaga I assume you cannot do that. Object is OOP base structure in Java, whereas lambdas (or, in other words, functional interfaces' instances) are functional programming structures. If your current architecture makes you trying to use lambda as OOP object, you most likely should do some redesigning – Steyrix Jan 06 '20 at 09:55

1 Answers1

4

You can't directly return your lambda expression like that. This is because a lambda expression's target type must be a functional interface.

You are currently creating your lambda expression in the context of a method's return statement, which means that the type of the lambda expression is that method's return type. This is not allowed:

Object supplier = () -> "this line will get COMPILE-ERROR. -> ?????????"; //NO

That's because the target type (Object) is not a functional interface. It's for the same reason that this is not allowed

static Object value() {
    return () -> "this line will get COMPILE-ERROR. -> ?????????"; //No
}

If you really want to do what you are trying to do, which is something you should avoid, you can do it indirectly:

static Object value() {
    MySupplier mySupplier = () -> "this line will get COMPILE-ERROR. -> ?????????";
    return mySupplier;
}

But you should not need to do this, and having MySupplier as the return type makes this code clean.

ernest_k
  • 44,416
  • 5
  • 53
  • 99
  • thank you man. It really do the trick. also It's NOT quite comfortable to write one more line of code just to make the compiler work. :D – harunaga Jan 06 '20 at 10:20
  • 1
    Yeah. But the `(...) -> ...` construct depends heavily on what you assign it to, what you return it as, or what argument you make it; and in all those cases it must be a functional interface. As for your code, it surely would be better if your return type were `MySupplier`. – ernest_k Jan 06 '20 at 10:25
  • 1
    kinda I understand why now. Thanks so much. writing one more line of code is better than some thing like "you can't... or it's not possible...." :D – harunaga Jan 06 '20 at 10:38