递归方法在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 是调用另一个函数的函数的值,不一定是调用链中的第一个函数。
我正在尝试使用递归方法实现重试机制。虽然该方法已经返回列表,但还会执行连续的代码行。
我确定我遗漏了一些非常明显的东西,训练有素的眼睛可以在一秒钟内发现。我怎样才能重做递归,所以我摆脱了最后的 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 是调用另一个函数的函数的值,不一定是调用链中的第一个函数。