Java 8 延迟执行方法
Java 8 Deferring Execution of Method
我有这样的 class 层次结构:
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: 根据评论,这里尝试更好的解决方案:
@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);
}
}
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
.
的情况下完成完全相同的工作
如果您做想要在单独的线程中运行这个逻辑,您可以创建一个调用doSomething
的Callable
。尽管如此,为了 运行 它在一个单独的线程中,你应该使用 ExecutorService
.
注意:一个FunctionalInterface
只能有一个抽象方法(它可以有额外的默认方法——因为它们不是抽象的)。
Java中使用 lambda 表达式的方式,要求在您的方法中使用功能接口来调用,并且 lambda 表达式必须实现它。这意味着功能接口必须采用 lambda 表达式所需的参数数量。它只能为空或 return 单个值。
如果您需要四个参数,则没有标准接口可以为您做到这一点(Callable 不接受参数)。您可以轻松定义自己的;查看 BiFunction 以了解应如何定义 QuadFunction。
我有这样的 class 层次结构:
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: 根据评论,这里尝试更好的解决方案:
@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);
}
}
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
.
如果您做想要在单独的线程中运行这个逻辑,您可以创建一个调用doSomething
的Callable
。尽管如此,为了 运行 它在一个单独的线程中,你应该使用 ExecutorService
.
注意:一个FunctionalInterface
只能有一个抽象方法(它可以有额外的默认方法——因为它们不是抽象的)。
Java中使用 lambda 表达式的方式,要求在您的方法中使用功能接口来调用,并且 lambda 表达式必须实现它。这意味着功能接口必须采用 lambda 表达式所需的参数数量。它只能为空或 return 单个值。
如果您需要四个参数,则没有标准接口可以为您做到这一点(Callable 不接受参数)。您可以轻松定义自己的;查看 BiFunction 以了解应如何定义 QuadFunction。