为什么代码在"返回"后仍在运行

Cha*_*Siu 0 java recursion

我发现我的代码在点击"返回表"后仍在运行 (我已经运行了调试模式,它真的向前移动到下一行,为什么一旦调用return语句,我的函数不应该立即结束(退出)?我的递归有什么问题吗?

public static HtmlTable getTableFromDomElement(DomElement element) throws Exception{

    if(element instanceof com.gargoylesoftware.htmlunit.html.HtmlTable){
        System.out.println("----YES!!!!-----");
        HtmlTable table = (HtmlTable) element;
        return table;
    }

    for(DomElement e : element.getChildElements()){         
            getTableFromDomElement(e);
        }

    throw new Exception("No HTML table found");
}
Run Code Online (Sandbox Code Playgroud)

输出:

----YES!!!!-----

Exception in thread "main" java.lang.Exception: No HTML table found

T.J*_*der 5

你需要在找到时停止搜索,但是你没有停止for循环.相反,返回null"未找到"的情况并在第一次看到非null时返回:

public static HtmlTable getTableFromDomElement(DomElement element) throws Exception {
    HtmlTable table;

    if(element instanceof HtmlTable){
        System.out.println("----YES!!!!-----");
        table = (HtmlTable) element;
        return table;
    }

    for(DomElement e : element.getChildElements()){         
         table = getTableFromDomElement(e);
         if (table != null) {
             return table;
         }
    }

    return null;
}
Run Code Online (Sandbox Code Playgroud)

(throws Exception如果没有任何代码正在调用则抛出异常.)另请注意,由于您明确导入com.gargoylesoftware.htmlunit.html(否则,您的HtmlTable返回类型声明将无效),因此com.gargoylesoftware.htmlunit.html.HtmlTable您无需进行instanceof检查.只是HtmlTable你需要的一切.

如果你需要一个在找不到时抛出的版本,它必须是一个包装函数.

public static HtmlTable getTableFromDomElementOrThrow(DomElement element) throws Exception{
    HtmlTable table = getTableFromDomElement(element);
    if (table == null) {
        throw new Exception("No HTML table found");
    }
    return table;
}
Run Code Online (Sandbox Code Playgroud)

(当然,它不具备成为一个包装的功能,你可以赶上在循环的每一次迭代例外,但由于不具有表的子元素不是一个特殊的条件,这不是一个合适的位置抛出异常.在每次循环迭代中抛出异常也会明显降低效率.)


或者这里是一个只在一个地方返回的重构版本(有时被认为是好的做法):

public static HtmlTable getTableFromDomElement(DomElement element) throws Exception {
    HtmlTable table = null;

    if(element instanceof HtmlTable){
        System.out.println("----YES!!!!-----");
        table = (HtmlTable) element;
    } else {
        for (DomElement e : element.getChildElements()){         
             table = getTableFromDomElement(e);
             if (table != null) {
                 break;
             }
        }
    }

    return table;
}
Run Code Online (Sandbox Code Playgroud)