I have a following program
import java.util.Scanner;
@FunctionalInterface
interface Retry {
int run(Runnable action, int maxAttempts, long delayBeforeRetryMs);
}
final class RetryUtils {
public static Retry retry= RetryUtils::retryAction; // assign the retryAction method to this variable
private RetryUtils() { }
public static int retryAction(
Runnable action, int maxAttempts, long delayBeforeRetryMs) {
int fails = 0;
while (fails < maxAttempts) {
try {
action.run();
return fails;
} catch (Exception e) {
System.out.println("Something goes wrong");
fails ;
try {
Thread.sleep(delayBeforeRetryMs);
} catch (InterruptedException interruptedException) {
throw new RuntimeException(interruptedException);
}
}
}
return fails;
}
}
class Retrying {
private static final int MAX_ATTEMPTS = 10;
private static final long DELAY_MS = 1;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
RetryUtils.retry.run(() -> System.out.println(scanner.nextLine()), MAX_ATTEMPTS, DELAY_MS);
}
}
And I see the method retryAction
returns int. Then how is public static Retry retry= RetryUtils::retryAction;
a valid assignment to object of type Retry ? How does this compile ? Whats happening behind the scenes ?
CodePudding user response:
It is not a function call to expect int as a return type. It is a lambda expression that kind of creates anonymous implementation of your Retry
interface. It is almost equal to this
public static Retry retry= new Retry(){
int run(Runnable action, int maxAttempts, long delayBeforeRetryMs)
RetryUtils.this.retryAction(action,maxAttemps,delayBeforeRetryMs)
}
The analogy is almost accurate due to the statics and how lambda expression actually works, but you should get the idea.