一个死循环导致的栈溢出实例:StackOverFlowError
实例 一个 导致 溢出 死循环
2023-09-14 08:58:22 时间
有一个功能,要用复选框组做成单选框效果,如果有三个复选框 CheckBox ,并且保证每次只能选中一个。刚开始添加了以下的值改变后的监听方法 addValueChangeListener ,却导致了栈溢出:
1 public static void checkBoxAddChangeListener(CheckBox checkBox1, CheckBox checkBox2, CheckBox checkBox3){ 2 checkBox1.addValueChangeListener(e -> { 3 checkBox2.setValue(!checkBox1.getValue()); 4 checkBox3.setValue(!checkBox1.getValue()); 5 }); 6 7 checkBox2.addValueChangeListener(e -> { 8 checkBox1.setValue(!checkBox2.getValue()); 9 checkBox3.setValue(!checkBox2.getValue()); 10 }); 11 12 checkBox3.addValueChangeListener(e -> { 13 checkBox1.setValue(!checkBox3.getValue()); 14 checkBox2.setValue(!checkBox3.getValue()); 15 }); 16 }
思考上面代码的逻辑,假如现在第二个复选框是选中状态,此时再选中了第一个复选框,会触发第一个复选框的监听事件,第二、三个复选按钮就变成了未选中状态。因为第二个复选框的状态改变了,会触发它的监听事件,此时第一、三个复选框会变成选中状态。因为第一个已经是选中状态了,所以不会触发值改变的监听器。但是第三个复选框的状态却变了,触发监听器事件,把第一、二个监听器变成未选中状态。此时会再次触发第一个复选框的监听器事件。如此往复循环,StackOverFlowError
正确做法之一就是,不要在值改变的时候就触发事件,要在复选框的值变成选中状态时,触发一次事件就好了。添加以下判断。
1 public static void checkBoxAddChangeListener(CheckBox checkBox1, CheckBox checkBox2, CheckBox checkBox3){ 2 checkBox1.addValueChangeListener(e -> { 3 if(checkBox1.getValue()){ 4 checkBox2.setValue(false); 5 checkBox3.setValue(false); 6 } 7 }); 8 9 checkBox2.addValueChangeListener(e -> { 10 if(checkBox2.getValue()){ 11 checkBox1.setValue(false); 12 checkBox3.setValue(false); 13 } 14 }); 15 16 checkBox3.addValueChangeListener(e -> { 17 if(checkBox3.getValue()){ 18 checkBox1.setValue(false); 19 checkBox2.setValue(false); 20 } 21 }); 22 }
这段代码还可以优化成一组复选框里只能选中一个值的方法,如下:
public static void checkBoxAddChangeListener(List<CheckBox> list){ for(int i=0; i<list.size(); i++){ CheckBox checkBox = list.get(i); checkBox.addValueChangeListener(e -> { if(checkBox.getValue()){ for (CheckBox tmp : list) { if (tmp == checkBox) { continue; } tmp.setValue(false); } } }); } }
附录:
但是最开始的错误方法,如果只有两个CheckBox,就不会报错了
public static void checkBoxAddChangeListener(CheckBox checkBox1, CheckBox checkBox2){ checkBox1.addValueChangeListener(e -> { checkBox2.setValue(!checkBox1.getValue()); }); checkBox2.addValueChangeListener(e -> { checkBox1.setValue(!checkBox2.getValue()); }); }
原因是:这两个监听器,每一个只能触发一个。
假如开始第二个复选框是选中状态,此时选中第一个复选框,触发第一个复选框的监听事件,把第二个复选框变成未选中状态。再触发第二个复选框的监听事件,此时把第一个复选框变成了选中状态。但是因为第一个复选框本身已经是选中状态了,所以它的值并没有改变,所以不会触发监听器事件。
原创文章,欢迎转载,转载请注明出处!
相关文章
- ASP.NET Core 6框架揭秘实例演示[29]:搭建文件服务器
- 【正则表达式】快速学习一个c语言的实例
- postgresql合并string_agg函数的实例
- java操作mongoDB查询的实例详解
- 一个SpringMVC的入门实例详解编程语言
- 深入解析Oracle中多个实例的优势(oracle多个实例)
- ABAP 一个隐藏 selection-screen block的实例详解编程语言
- 利用Oracle创建一个实例:指南(oracle创建一个实例)
- 如何在一个服务器上运行多个mongodb实例(mongodb多实例)
- Linux驱动程序开发:一个实例案例(Linux驱动程序开发实例)
- 构建MSSQL连接――一个实践实例(mssql 连接实例)
- 一键接入多实例Redis让项目扩展更便捷(一个项目接多个redis)
- MySQL实例如何进行分库管理(mysql 一个实例分库)
- 利用Oracle云服务器完成实例重置(oracle 云服务器实例重置)
- Oracle 采用一库多实例架构解决数据管理问题(oracle 一库多实例)
- 一个实例告诉你:Kaggle 数据竞赛都有哪些套路
- jQueryAjax方法调用Asp.NetWebService的详细实例代码
- 鼠标移动到图片名上,显示图片的简单实例
- 一个简单的python程序实例(通讯录)
- python获取beautifulphoto随机某图片代码实例
- Python写的一个简单DNS服务器实例
- php实现singleton()单例模式实例
- PHP内存缓存Memcached类实例
- Python实现备份文件实例