通过多次递归调用保持信息

时间:2015-11-04 12:59:39

标签: java recursion override

我正在扩展第三方类并重写一个我已经“递归”的方法,如下所示:

public class SubFoo extends Foo {
    ....
    @Override
    public void bar(...) {
        recursiveSpecificSet.add(...);
        if(recursiveSpecificSet.contains(...)){ 
            ...
            methodCallThatCallsBar(...);
            ...
        }
    }
}

由于此方法被覆盖,我无法控制方法签名。我想通过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方法的多次调用也可能发生在同一个线程中,因此线程局部变量将不起作用。

2 个答案:

答案 0 :(得分:1)

如果我理解你的问题,答案不是让bar递归,而是让bar调用一个递归的私有帮助方法。

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

private void helper(Set<String> recursiveSpecificSet) {
    ...
    helper(recursiveSpecificSet);
    ...
}

答案 1 :(得分:1)

使用存储递归深度和有效负载数据的threadlocal。如果在输入bar()时threadlocal为null,则使用深度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();
        }
    }
}