可以用finally块调用try-catch语句所在的方法吗



我制作了一个开关用例语句菜单,其中一个选项是System.exit(0(;。这一切都围绕着一个尝试,最后调用了所有这些都在其中的方法。你们会不推荐这种风格的循环吗?还是我都很好?

public void Run() {
Scanner myObj = new Scanner(System.in);
int menuInput;

try {
System.out.println(" 1) call somethingn"
+"2) quit");

menuInput = myObj.nextInt();
myObj.nextLine();

switch(menuInput) {
case 1:
something();
break;
case 2:
System.exit(0);
break;
}

}catch (Exeption e ){
System.out.println("Something went wrong.");

}finally{
Run();
}
}

否。

这里有一个无限递归。最终你会溢出堆栈。

使用实际循环:

while (true) {
try {
// ...
} catch (Exception e) {
// ...
}
}

而且您几乎从不想调用System.exit。只是break循环。

这是合法代码吗?对

你有推荐的吗?编号

如果该方法抛出异常,那么它很可能会重新调用它并再次抛出。请参阅下面的报价。

在没有尝试补救的情况下,在一个紧密的循环中再次调用它,至少等待恢复和计数失败(3次三振?(,最终只会在这里陷入失败和堆栈溢出的紧密循环。

因此:

你能确定重试可能有效的错误,并且只在这些错误上重试吗?

几乎可以肯定的是,在重试之前应该包括某种"后退"等待。

始终(始终!(包含一个最大重试次数,超过该次数后您将接受失败。

根据我的经验,重试时唯一可行的故障是"服务不可用",即间歇性中断。

它可能不相关,但像(比如(无效凭据之类的事情不会自行修复,理想情况下你不会重新提交这些凭据。这尤其是因为你最终锁定了帐户,状态甚至更糟,可能会给其他使用有效凭据的人带来问题。。。

另一种情况是(比如(找不到文件,并且您使用不存在文件作为轮询某个文件的方式。

这是一个糟糕的设计模式,也是对异常处理的滥用。

在这些情况下,您应该更喜欢使用某种类型的存在性检查,不要让常规活动与问题的异常处理混淆。

此外,如果您确实对每次尝试进行了重试日志记录(以后查看事情是否顺利运行或在重试场景中是否延迟可能会很有用,即使最终通过(。但重试时总是区分"警告"one_answers"认输"和失败时的"错误"。

public class Runner {

private static int MAX_RETRIES=3;
private static int BACK_OFF_MILLIS=30000;

public void Run() throws Exception,InterruptedException {
final int TRIES=3;//In reality may be configured.
int trycount=1;
for(;;){
try{
tryRun();
return;
}catch(Exception e){
String message=e.getMessage();
if(trycount>=MAX_RETRIES){
System.out.println("*FAILED*: "+e.getMessage());
throw e;
}
boolean retriable=true;
//Any tests for non-retriable exceptions here...
if(!retriable){
System.out.println("*FAILED*: non-retriable exception - "+e.getMessage());
throw e;
}
++trycount;   
System.out.println("Warning: "+e.getMessage()+" retrying "+ trycount+" of "+TRIES);
try {
Thread.sleep(trycount*BACK_OFF_MILLIS);//Some kind of back-off...
}catch(InterruptedException ie){
System.out.println("*FAILED*: Interrupted. Aborting.");
throw ie;
}
continue;
}
}
}

public void tryRun() throws Exception{
//Real workload goes here!
}
}

注意:这里的退让策略非常简单。当涉及到停机时,通常建议实施随机元素和增加的回退,如1分钟、10分钟、25分钟。但这本身就是一个话题。

我不确定是谁说的,但这句流行的话似乎很有意义。

精神错乱的定义是一遍又一遍地做同样的事情并且期望不同的结果

相关内容

  • 没有找到相关文章

最新更新