【问题标题】:return statement inside try catch and if else clausetry catch 和 if else 子句中的 return 语句
【发布时间】:2023-10-08 06:23:01
【问题描述】:

问题是我的代码中发生了一些奇怪的事情; 让我们来看我的例子(我清理了一下):

public int foo() throws IOException {
        if(redirect_url.indexOf("statement_1") != -1){
            if(check() == true){
                //do something
            }else{
               //do something
                foo(); //yep, recursive call
            }
        }else if(redirect_url.indexOf("statement_2") != -1) {
            map.clear();
            bar();
            map.put("val", 1);
            map.put("val2", "2");
            foo(); //yep, recursive call; Remember this line!!
        }else if(redirect_url.indexOf("statement3") != -1) {
            return AUTH_SUCCESS;
        }else if(redirect_url.indexOf("statement4") != -1){
            return AUTH_SUCCESS;
        }else {
            return AUTH_FAILED;
        }

    }catch (Exception e){
        return AUTH_FAILED;
    }
    return AUTH_FAILED;
}

有一个小函数被另一个函数调用,我们称之为buzz

public void buzz(){
     try {
         switch (signInAttempt()){
             case AUTH_SUCCESS:
                 //do smth
                 return true;
             case AUTH_FAILED:
                 //do smth
                 return false;
             case ACCESS_REQUEST:
                    //do smth
             default:
                 return false;
             }
      } catch (IOException e) {
            e.printStackTrace();
        }
}

当我发现我的代码中存在逻辑错误并发现有趣的事情时,我打开了我很棒的调试器。

假设redirect_url 字符串有“statement4”子字符串,这样第四个elseif 子句(不计算内部elseif 子句)会进入并返回AUTH_SUCCESS。我是这么想的。

问题是,当触发返回 AUTH_FAILED 时,下一条指令在第二个 else if 语句中调用 foo() 函数。我不知道为什么会发生这种情况。这么奇怪。和想法?

UPD 1: 类中定义的常量: 示例

private static final int AUTH_SUCCESS      = 4;

UPD 2 更多代码:

满足调用函数

public boolean rollIn(){

        try {
            switch (signInAttempt()){
                case AUTH_SUCCESS:
                    //do smth
                case AUTH_FAILED:
                    return false;
                case ACCESS_REQUEST:
                    return true;
                default:
                    return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return true;
    }

终于见到病人了:

 public int signInAttempt() throws IOException {

        try {

            /*connection*/
            this.doc = connection.parse();

            System.out.println(redirect_url);
            if(redirect_url.indexOf("authorize") != -1){
                if(findCaptcha() == true){
                    signInAttempt();
                }else{
                    authData.clear();
                    signInAttempt();
                }
            }else if(redirect_url.indexOf("authcheck") != -1) {
                authData.clear();
                authData.put("v1", 1);
                authData.put("v2", 2);
                System.out.println(action_url);
                signInAttempt();
            }else if(redirect_url.indexOf("__q_hash") != -1) {
                System.out.println("AUTH SUCCESS");
                return AUTH_SUCCESS;
            }else if(redirect_url.indexOf("access_token") != -1){
                return AUTH_SUCCESS;
            }else {
                return AUTH_FAILED;
            }

        }catch (Exception e){
            return AUTH_FAILED;
        }
        return AUTH_FAILED;
    }

类似的东西

【问题讨论】:

  • 您的问题目前还不清楚。如果您提供minimal reproducible example,会更容易为您提供帮助。
  • 您的方法不接受任何输入,但您的 if 语句依赖于当前状态。调试这种类型的代码很困难。考虑重构您的代码,使该方法仅使用传入的参数。
  • 递归调用?那你不想要return foo();吗?
  • @FishStix ,好吧,我当然是从有输入的函数开始的,但后来我发现这个函数经常使用公共值,我把它放到类字段中。是的,我看到代码有多糟糕:(
  • @JaroslawPawlak,好吧,我做到了,它解决了我的问题。您应该将此作为答案发布,我也想要一些解释。

标签: java try-catch


【解决方案1】:

在你进行递归调用的地方,你应该有return foo();

一个简短的解释它现在是如何工作的 - 没有return

  1. 第一次调用该方法
  2. 它进行递归调用
  3. 递归调用执行并返回一个值,因此我们回到了第一次调用的范围内
  4. 递归调用返回的值被忽略 - 你没有分配或返回它
  5. 在 if 语句之外继续执行,没有捕获到异常,所以它转到您的最后一条语句 return AUTH_FAILED;

因此,即使递归调用返回AUTH_SUCCESS,第一次调用也会忽略它并返回AUTH_FAILED

【讨论】: