【问题标题】:Java 8 Deferring Execution of MethodJava 8 延迟方法的执行
【发布时间】:2017-10-01 20:12:15
【问题描述】:

我有一个这样的类层次结构:

public abstract class AbstractFoo {
    abstractMethod(/*parameters*/) {
        //do something;
    }
}

public class Foo extends AbstractFoo {
    public String doSomething(int id, int value, FooB b, FooC c) {
        //do something;
    }

    public void doSomethingElse() {
        abstractMethod(param1, param2);
    }
}

我希望能够将doSomething 方法作为方法参数传递给abstractMethod。我尝试过这样的事情:

public abstract class AbstractFoo {
    abstractMethod(/*parameters*/, Callable<String> method) {
        //do something;
        method.call();
    }
}

public class Foo extends AbstractFoo {
    Callable<String> doSomething = (int id, int value, FooB b, FooC c) -> {
        //do something;
    };

    public void doSomethingElse() {
        abstractMethod(param1, param2, doSomething);
    }
}

但我收到以下错误:

Error:(37, 40) java: incompatible types: incompatible parameter types in lambda expression: wrong number of parameters: expected 0 but found 4

很明显,我没有正确执行此操作。实现我想要的正确 Java 8 方法到底是什么?

编辑1:基于cmets,这里尝试一个更好的解决方案:

@FunctionalInterface
public interface Fazz<T> {
    String createStuff(int id, int value, T value1, T value2);
}

public abstract class AbstractFoo {
    abstractMethod(Fazz<T> interfc) {
        interfc.createStuff(/* pass parameters? */);
    }
}

public class Foo extends AbstractFoo {
    Fazz<String> doSomething = (int id, int value, String value1, String value2) -> {
        //do something;
    };

    public void doSomethingElse() {
        abstractMethod(doSomething);
    }
}

【问题讨论】:

  • 有点不清楚你在做什么以及为什么要做这样的事情......你可以定义一个带有 4 个参数的 @FunctionalInterface,或者将参数作为参数传递,但仍然传递一个 @ 987654328@;但无论哪种方式对我来说都没有意义

标签: java callback java-8 deferred callable


【解决方案1】:

Callable 接口只有一种方法:call(),它接受零参数,因此会出错。

如果你希望能够传递一个 lambda,你应该实现一个 FunctionalInterface,例如:

@FunctionalInterface
interface DoSomething<T> {
    T doSomething(int id, int value, FooB b, FooC c);
}

然后你就可以创建并传递这样一个 lambda:

DoSomething<String> doSomething = (int id, int value, FooB b, FooC c) -> {
        //do something (that returns a string)
};

此外,Callable 用于在单独的线程中运行逻辑。您在上面发布的代码并没有这样做,这意味着您可以在不使用 Callable 的情况下完成完全相同的工作。

如果您确实想在单独的线程中运行此逻辑,您可以创建一个调用doSomethingCallable。不过,为了在单独的线程中运行它,您应该使用ExecutorService

注意:FunctionalInterface 只能有一个抽象方法(它可以有额外的默认方法——因为它们不是抽象的)。

【讨论】:

  • 所以我需要创建这个接口,然后在我的Foo 类中实现它?
  • @Richard 是的。 lambda 的实现,你可以在任何你需要的地方实现它!
  • 请注意,函数接口的声明方式应声明 createStuff 的方法签名以返回 T 而不是字符串。
  • 我仍然不知道如何实际实现这些
  • @Richard 你让我很难帮助你:说“我做的不对”和“我不知道”太含糊了......如果你会使用代码在上面的答案中它应该可以工作,如果没有,您应该提供更多信息:它是编译错误吗?如果是这样 - 错误是什么以及它是从哪一行触发的?是运行时错误吗?如果是这样,堆栈跟踪是什么,哪一行导致它?帮助我们帮助你!
【解决方案2】:

Java 中使用 lambda 表达式的方式,要求在您的方法中使用函数式接口来调用,而 lambda 表达式必须实现它。这意味着函数式接口必须采用 lambda 表达式所需的参数数量。它只能为 void 或返回单个值。

如果您需要四个参数,则没有标准接口可以为您做到这一点(Callable 不接受参数)。您可以轻松定义自己的;查看 BiFunction 以了解应该如何定义 QuadFunction。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多