Java递归函数调用疑惑:未输入值时基例语句为何执行?
搞懂递归基例触发与程序初始化的小坑
嘿,我来帮你拆解这个问题——你看到的8次Hello World打印,根本不是基例条件没满足就执行,而是程序初始化阶段多次触发了基例逻辑,咱们一步步理清楚:
首先,你的初始count值直接触发了基例
你在CirclePane2的构造函数里把count设成了0:
public CirclePane2() { this.count = 0; }
而你的displayCircle方法里,基例条件就是count == 0啊!所以第一次调用displayCircle的时候,直接就走进基例代码块,打印Hello World了。这部分逻辑是完全符合递归规则的,不是bug。
为什么会打印8次?因为监听器被多次触发了
你在start方法里给Scene的宽高属性都加了监听器,只要窗口尺寸变了就调用circlePane.createCircle():
scene.widthProperty().addListener(ov -> circlePane.createCircle()); scene.heightProperty().addListener(ov -> circlePane.createCircle());
当你启动程序调用stage.show()后,窗口不会一下子就变成400x400,它会经历好几次尺寸变化:从初始的0x0,到布局计算时的中间尺寸,最后才到你设置的目标尺寸。每一次尺寸变化都会触发对应的监听器,调用createCircle,而每次createCircle都会带着count=0去调用displayCircle,自然就打印了好几次Hello World,叠加起来就是8次啦。
验证递归正常逻辑的小方法
如果你想看到递归分支执行的过程,而不是直接进入基例,可以试试:
- 把
CirclePane2构造函数里的count初始值改成1或者更高,比如this.count = 2,启动程序后就能看到递归调用else分支的过程了。 - 在输入框里输入一个大于0的数,比如3,这时候
count被更新,displayCircle会进入else分支,递归调用4次count-1的实例,直到所有分支都走到count=0的基例,这时候你会看到大量的Hello World(比如输入3的话会有4^3=64次打印)。
小优化:避免初始化时的频繁触发
要是不想在程序刚启动时就频繁打印,可以给监听器加个判断,只有当尺寸大于0的时候才执行:
scene.widthProperty().addListener((ov, oldVal, newVal) -> { if (newVal.doubleValue() > 0) circlePane.createCircle(); }); scene.heightProperty().addListener((ov, oldVal, newVal) -> { if (newVal.doubleValue() > 0) circlePane.createCircle(); });
或者在createCircle方法里先判断当前宽高是否有效(大于0),再执行后续逻辑。
内容的提问来源于stack exchange,提问作者Mohit Tomar
相关产品推荐
相关产品推荐

