【问题标题】:incompatible types: Object is not a functional interface netbeans-11 java不兼容的类型:对象不是功能接口 netbeans-11 java
【发布时间】:2020-01-06 09:35:05
【问题描述】:

我对 Java 8 的 lambda 表达式很陌生

我尝试了以下并得到编译错误

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";
            }
        };

    }
}

我的问题是“是否可以将 lambda 表达式用作普通对象。我想做一些类似的事情

    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";
        });
    }

我做了很多搜索,但没有运气。有什么解决方法吗? 提前致谢!


更新:在对 lambda 表达式有了更深入的了解之后,问题是如何让编译器知道要编译到的 lambda 表达式的目标类型。 所以 ernest_k 的答案可以改进为

return (MySupplier) () -> "this line will work";

【问题讨论】:

  • 为什么不在value()方法中返回MySupplier而不是返回Object
  • 只是一个测试代码。有时我想返回一个值,如字符串、整数或对象,有时我想返回一个函数作为 Lambda 以获得更短的代码。所以我把它作为返回类型的对象。但遗憾的是 lambda 没有被编译。
  • static Object value() 更改为 static MySupplier value() 将起作用
  • 我想做的是使用功能接口作为其他对象。正如我在代码中评论的那样,使用内部类将被编译,但 lambda 表达式不会被编译。
  • @harunaga 我想你不能那样做。 Object 是 Java 中的 OOP 基础结构,而 lambdas(或者换句话说,函数式接口的实例)是函数式编程结构。如果您当前的架构让您尝试使用 lambda 作为 OOP 对象,您很可能应该重新设计

标签: java netbeans java-8 functional-interface netbeans-11


【解决方案1】:

你不能像那样直接返回你的 lambda 表达式。这是因为 lambda 表达式的目标类型必须是函数式接口。

您当前正在方法的 return 语句的上下文中创建 lambda 表达式,这意味着 lambda 表达式的类型是该方法的返回类型。这是不允许的:

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

这是因为目标类型 (Object) 不是函数式接口。出于同样的原因,这是不允许的

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

如果你真的想做你想做的事,这是你应该避免的,你可以间接地去做:

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

但您不应该这样做,并且将MySupplier 作为返回类型会使这段代码干净。

【讨论】:

  • 谢谢你。它真的可以解决问题。另外,为了让编译器工作而多写一行代码也不是很舒服。 :D
  • 是的。但是(...) -> ... 构造在很大程度上取决于您将其分配给什么,您将其返回为什么,或者您提出了什么论据;在所有这些情况下,它必须是一个功能接口。至于你的代码,如果你的返回类型是MySupplier肯定会更好。
  • 我现在明白为什么了。非常感谢。多写一行代码比“你不能……或者不可能……”这样的事情要好:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-09
  • 2015-11-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多