我不知道以下事情是否可行。我希望Runnable
run()
方法包含Runnable
本身,即
reconnects = 3;
Runnable executeAfter = () -> {
if ( --reconnects < 0 ) {
println("%nStop using port %d.", this.port);
//...
} else { // try to reconnect
println("%nReconnecting...");
cmdRun = new CmdRun(command, executeAfter);
(new Thread(cmdRun)).start();
//...
}
};
这样的事情是否可能?如果是这样,怎么样? (CmdRun
的构造函数为CmdRun(String command, Runnable executeAfter)
)
答案 0 :(得分:2)
lambda必须在这吗?如果没有,切换到较旧的等效语法应该很简单:
一个例子:
public class TestLambda {
static int count = 0;
public static void main(String[] args) {
// lambda not going to work
//Runnable foo = () -> { if (count < 5) { call(foo); } };
// nor
//Runnable foo = () -> { if (count < 5) { call(this); } };
// using old way of anonymous inner class will work
Runnable foo = new Runnable() {
@Override public void run() {
if (count < 5) {
call(this);
}
}
};
foo.run();
}
public static void call(Runnable action) {
count++;
System.out.println("in call " + count);
action.run();
}
}
答案 1 :(得分:1)
最简单的方法可能是将lambda的内容放在方法中,并使用方法引用来定义Runnable。
答案 2 :(得分:1)
Runnable的run()不能包含自我引用,因为它是非法的。 我不完全确定你想要实现的目标,但这样的事情应该有效:
class CmdRun implements Runnable {
final Object command;
final Runnable runnable;
final Runnable executeAfter = () -> {
if ( --reconnects < 0 ) {
System.out.println("%nStop using port %d." + port);
//...
} else { // try to reconnect
System.out.println("%nReconnecting...");
CmdRun cmdRun = new CmdRun(command);
(new Thread(cmdRun)).start();
//...
}
};
public CmdRun(Object command) {
this.command = command;
this.runnable = executeAfter;
}
@Override
public void run() {
runnable.run();
}
}
答案 3 :(得分:1)
简答:否。
答案很长:
您的代码会给您一个语法错误。为什么? lambda中使用的executeAfter
未初始化;它仅在lambda定义的完整主体之后初始化。
例如,请考虑以下示例。
int i;
sum(i, 5); // Syntax error!! Variable i is not initialized...
你的情况类似。在lambda中,executeAfter
未初始化。如上所述,它仅在lambda定义的完整主体之后初始化。
节点的另一个要点是变量reconnects
必须是final才能在lambda中使用。如果它是最终变量,那么您不能在if条件中使用--
运算符。
答案 4 :(得分:1)
实际上,如果您不介意引入新界面(或者如果您经常需要此类功能),可以使用以下内容:
@FunctionalInterface
interface RecursiveRunnable extends Runnable {
default void run() {
run(this);
}
public void run(RecursiveRunnable runnable);
}
现在允许您以递归方式调用runnable,例如:
int maxTries = 3;
AtomicInteger counter = new AtomicInteger();
RecursiveRunnable foo = runnable -> {
if (counter.getAndIncrement() < maxTries) {
println("Reconnecting... %n");
runnable.run(); // same as: runnable.run(runnable)
} else {
println("Stop using port %d%n", port);
}
};