Home > OS >  How is this method reference a valid one ? What is happeneing behind the scenes?
How is this method reference a valid one ? What is happeneing behind the scenes?

Time:07-10

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.

  • Related