Java递归方法中局部变量的外化

Java递归方法中局部变量的外化,java,recursion,Java,Recursion,我有一个递归的方法,它有本地的字符串变量: private void recursiveUpdate(int id){ String selectQuery="Select ..."; String updateQuery="Update or rollback ..." ... for(int childID: children) recursiveUpdate(childID); } 是否有任何理由将本地字符串变量外部化如下: priva

我有一个递归的方法,它有本地的
字符串
变量:

private void recursiveUpdate(int id){
    String selectQuery="Select ...";
    String updateQuery="Update or rollback ..."

    ...

    for(int childID: children)
        recursiveUpdate(childID);
}
是否有任何理由将本地字符串变量外部化如下:

private static final String selectQuery="Select ...";
private static final String updateQuery="Update or rollback ..."

private void recursiveUpdate(int id){
    ...

    for(int childID: children)
        recursiveUpdate(childID);
}

对。您可能希望将变量外部化。如果将其作为局部变量,则根据调用堆栈的大小,可能会快速累积许多字符串对象,从而降低效率。如果在递归方法中编辑字符串,则更糟糕。此外,您不会像我看到的那样对字符串进行更改,因此如果用作“引用”,最好将其外部化。

在前一种情况下,您依赖于编译器来识别这些字符串在所有调用中都是不变的,因此它不需要为每次调用
recursiveUpdate
提供每个变量的新副本,而在后一种情况下,这是毫无疑问的。

从技术角度来看,两者之间的差异应该可以忽略不计,因为在任何一种情况下,您总是使用相同的字符串实例。如果您在每次调用中解析这些查询,那么您也可以考虑将其外部化(例如使用准备好的语句)。
从开发的角度来看,我可能会将查询外部化,以将它们与调用逻辑分开。

通常,在进行递归调用时,您应该关注堆栈内存的大小。这告诉cpu在方法完成时跳转到哪里。它包含您的方法参数和返回位置

在方法体中实例化的对象保存在堆中。在这种情况下,我认为编译器会发现这些是常量,并将它们保存到静态内存中。堆要大得多,并且在实例化对象时更有可能在递归中生存下来,所以我不必担心。。通过将对象移出,您将在堆中节省一点空间


在我看来,如果值始终相同(没有动态),最好将变量移出。这样,如果它们发生变化,您可以很容易地找到它们。

字符串是不可变的。编译器还不够聪明,不能复制吗?因为这些字符串是文本,所以您不会在每次调用时创建新的副本。编译器无论如何都会将它们外部化。谢谢!你能解释一下在这种情况下解析会发生什么变化吗?@sberezin好吧,解析查询通常需要一些时间,例如,构建一个抽象语法树等等。因为查询似乎没有变化,你可以这样做一次,然后用更新的参数调用解析过的查询。哦,是的,我明白你的意思了