Java 通过多次递归调用持久化信息

Java 通过多次递归调用持久化信息,java,recursion,overriding,Java,Recursion,Overriding,我扩展了一个第三方类,并重写了一个方法,我将其设置为“递归”,如下所示: 由于这个方法被重写,我在方法签名中没有控制权。我希望通过recursiveSpecificSet将父递归调用的信息传递给其子递归调用,但我希望这些信息特定于该递归链。例如: SubFoo sf = new SubFoo(); sf.methodCallThatCallsBar(...); // first call calls bar recursively 3 times sf.methodCallThatCallsBa

我扩展了一个第三方类,并重写了一个方法,我将其设置为“递归”,如下所示:

由于这个方法被重写,我在方法签名中没有控制权。我希望通过recursiveSpecificSet将父递归调用的信息传递给其子递归调用,但我希望这些信息特定于该递归链。例如:

SubFoo sf = new SubFoo();
sf.methodCallThatCallsBar(...); // first call calls bar recursively 3 times
sf.methodCallThatCallsBar(...); // second call calls bar recursively 5 times
在上面的代码中,第一个调用的recursiveSpecificSet变量不应干扰第二个调用的recursiveSpecificSet


这可能吗?我知道您通常可以通过方法参数在递归迭代之间传递信息,但我无法控制方法签名。对bar方法的多次调用也可能发生在同一个线程中,因此线程局部变量将不起作用。

如果我正确理解您的问题,答案不是使
bar
递归,而是使
bar
调用递归的私有助手方法

@Override
public void bar() {
    helper(new HashSet<>());
}

private void helper(Set<String> recursiveSpecificSet) {
    ...
    helper(recursiveSpecificSet);
    ...
}
@覆盖
公共空白栏(){
helper(新HashSet());
}
私有void帮助器(集合递归指定集合){
...
helper(recursiveSpecificSet);
...
}

使用存储递归深度和有效负载数据的threadlocal。如果在输入
bar()
时threadlocal为空,则使用深度1初始化它,否则增加深度。离开
bar()
,减小深度,如果在
1
下,则删除threadlocal。最后,您可能必须这样做,以便在抛出异常时不会中断

public void bar() {
    if (threadLocal == null) {
        threadLocal.set(new Context(recursiveSpecificSet));
    }
    threadLocal.get().increaseDepth();

    try {
        ...
        methodCallThatCallsBar(...);
        ...
    }
    finally {
        threadLocal.get().decreaseDepth();
        if (threadLocal.get().isExitRecursion()) {
            threadLocal.remove();
        }
    }
}

谢谢你的回复!这当然对我的措辞有效,但为了简单起见,我去掉了一些复杂性。我已经更新了问题。本质上,我不直接调用bar()方法。它实际上是由另一个第三方方法调用的。所以我不能创建一个helper方法,因为它不是直接递归。只有当对bar()的每次调用都在线程中自包含时,线程局部变量才会起作用,对吗?事实并非如此。您的意思是,您有一个递归调用,其中递归跨越多个线程?就像你在递归循环中的某个地方实例化一个新线程,然后在这个新线程中继续递归一样?如果是这样的话,我们需要知道所有的约束条件,那么,您将越来越多的约束条件添加到问题中。你仍然认为一个递归调用和什么被认为是一个单独的调用?不,我的意思是,我只能有一个线程。如果我只有一个线程,我的ThreadLocal变量对于每个递归调用都将始终是相同的。我希望每个递归链都有自己的变量,因为你计算递归深度,当你退出最外层的调用时,你会删除ThreadLocal的内容。随后再次调用
bar()
时,将使用另一个值再次初始化threadlocal。
public void bar() {
    if (threadLocal == null) {
        threadLocal.set(new Context(recursiveSpecificSet));
    }
    threadLocal.get().increaseDepth();

    try {
        ...
        methodCallThatCallsBar(...);
        ...
    }
    finally {
        threadLocal.get().decreaseDepth();
        if (threadLocal.get().isExitRecursion()) {
            threadLocal.remove();
        }
    }
}