递归方法在return之后执行代码

Code is executed after return in recursive method

我正在尝试使用递归方法实现重试机制。虽然该方法已经返回列表,但还会执行连续的代码行。

我确定我遗漏了一些非常明显的东西,训练有素的眼睛可以在一秒钟内发现。我怎样才能重做递归,所以我摆脱了最后的 return null 语句。根本不需要。

这是完整的代码:

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class Retryer {

    private static final int RETRY_COUNT = 3;
    private static final long RETRY_DELAY = 2; // in seconds

    private static int tryCounter = 0;

    public Retryer() {}

    public void execute() {
        List<String> downloadedFiles;
        try {
            Callable<List<String>> c = new AsyncFileDownloader();
            downloadedFiles = c.call();
        } catch (Exception e) {
            System.out.println("Ops! Starting retry");
            ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
            downloadedFiles = retry(scheduledExecutorService, 0);
            System.out.println("Retry ended");
            if (downloadedFiles == null || downloadedFiles.isEmpty()) {
                System.out.println("Sorry. Will exit now");
                System.exit(0);
            }
        }

        System.out.println("Finished successfully with " + downloadedFiles.size() + " in list.");
    }

    private List<String> retry (ScheduledExecutorService ses, int retryCounter) {
        if (retryCounter == RETRY_COUNT) {
            System.out.println("Retry limit reached. Exiting");
            ses.shutdown();
            return null;
        }
        try {
            System.out.println("Retry attempt # " + (retryCounter+1) + " will start in " + RETRY_DELAY + " seconds ...");
            ScheduledFuture sf = ses.schedule(new AsyncFileDownloader(), RETRY_DELAY, TimeUnit.SECONDS);
            List<String> downloadedFiles = (List<String>) sf.get();
            ses.shutdown();
            System.out.println("In retry. success " + downloadedFiles );
            return downloadedFiles;
        } catch (Exception e) {
            System.out.println("--recursive calling");
            retry(ses, ++retryCounter);
        }
        System.out.println("--returning null!!! This shouldn't happen");
        return null;
    }

    class AsyncFileDownloader implements Callable<List<String>> {
        @Override
        public List<String> call() throws Exception {
            synchronized (this) {
                tryCounter++;
                System.out.println("--in pull");
                if (tryCounter < 3) throw new IOException("Some bad thing happened");
                List<String> retList = new ArrayList<>();
                retList.add("file1");
                retList.add("file1");
                return retList;
            }
        }
    }
}

这里输出:

--in pull
Ops! Starting retry
Retry attempt # 1 will start in 2 seconds ...
--in pull
--recursive calling
Retry attempt # 2 will start in 2 seconds ...
--in pull
In retry. success [file1, file1]
--returning null!!! This shouldn't happen
Retry ended
Sorry. Will exit now

如果第一次执行进入catch块,则递归调用重试。一旦第二次调用 returns,您将继续执行第一次调用中 catch 块之后的代码,导致您打印“returning null”。

你真正想要的可能是return递归调用的值。请记住,return return 是调用另一个函数的函数的值,不一定是调用链中的第一个函数。